Is it possible to scan strings with spaces, and then other unlike int variables. For instance, if I wanted to input the name of a tool, then it's price, how would I differentiate between the two in the scan line?
Is it possible to scan strings with spaces, and then other unlike int variables. For instance, if I wanted to input the name of a tool, then it's price, how would I differentiate between the two in the scan line?
>> Strings and white space
I don't quite understand what you're asking. Example, please?
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }
Here's a sample of code:
My problem is that I can't get scanf to differentiate beween the variables for 'toolname' and 'quantity'.Code:void newrecord(FILE *fptr) { struct inventory tool = {0, "", 0, 0.0}; int recordnum; printf("Enter new record (1-100): "); scanf("%d", &recordnum); fseek(fptr, (recordnum - 1) * sizeof(struct inventory), SEEK_SET); fread(&tool, sizeof(struct inventory), 1, fptr); if(tool.recordnum != 0){ printf("Record #%d already contains information.\n", tool.recordnum); } else{ printf("Enter Tool Name, Quantity and Cost: "); scanf("%s%d%lf", &tool.toolname, &tool.quantity, &tool.cost); tool.recordnum = recordnum; fseek(fptr, (tool.recordnum - 1) * sizeof(struct inventory), SEEK_SET); fwrite(&tool, sizeof(struct inventory), 1, fptr); }/*end else*/ }
HOPE YOU UNDERSTAND.......
By associating with wise people you will become wise yourself
It's fine to celebrate success but it is more important to heed the lessons of failure
We've got to put a lot of money into changing behavior
PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
IDE- Microsoft Visual Studio 2008 Express Edition
>> My problem is that I can't get scanf to differentiate beween the variables for 'toolname' and 'quantity'.
Why? Aren't you entering the values separated by spaces? It should work fine. Oh and one more thing, you should be checking return values (scanf, fseek, fread, etc).
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }
I am, but the problem is with input like "Sledge Hammer" and then 7.50 for cost. I need to figure out how to enter strings that have spaces, and then input value for other variables.
>> the problem is with input like "Sledge Hammer" and then 7.50 for cost.
I see. In that case, you'll either need to input them separately (eg: one variable per line) or else use fgets and split the input "manually".
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }
1 - Read the FAQ.
2 - Read a line from the file using fgets.
3 - Split it using sscanf.
Actually... it looks like you're reading records one whole structure at a time. In which case, you shouldn't need to do any of this. Just fwrite the whole structure, and then later fread it back in.
Quzah.
Hope is the first step on the road to disappointment.
Here's a quick-and-dirty example using fgets and sscanf:
Code:int main( void ) { const int size = 1024; char buffer[ size + 1 ]; char name[ size + 1 ]; int index = 0, quantity = 0; double cost = 0; printf( "Enter name, quantity, and cost >" ); if( fgets( buffer, size, stdin ) ) { while( buffer[ index ] != 0 && !isdigit( buffer[ index + 1 ] ) ) ++index; strncpy( name, buffer, index ); name[ index ] = 0; if( sscanf( &buffer[ index ], "%d%lf", &quantity, &cost ) == 2 ) { printf( "Name: %s\nQuantity: %d\nCost: %lf\n", name, quantity, cost ); } else { puts( "Error: invalid input" ); } } else { puts( "Error: input error" ); } return 0; }
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }
Thanks for that. Why do you set name[index] to zero?
>> Why do you set name[index] to zero?
Just to be sure that it gets null terminated (strncpy doesn't guarantee it).
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }
Thanks again for the help. OK, I've changed your code around a little to fit my program. This is the new function prototype to insert a new record. See below:
Below is a shot of the program when running.Code:void newrecord(FILE *fptr) { struct inventory tool = {0, "", 0, 0.0}; int recordnum, i = 0; char temp[30]; printf("Enter new record (1-100): "); scanf("%d", &recordnum); fseek(fptr, (recordnum - 1) * sizeof(struct inventory), SEEK_SET); fread(&tool, sizeof(struct inventory), 1, fptr); if(tool.recordnum != 0){ printf("Record #%d already contains information.\n", tool.recordnum); } else{ printf("Enter name, quantity, and cost: "); fgets( temp, 30, stdin ); while(temp[i] != 0 && !isdigit(temp[i + 1])){ ++i; strncpy(tool.toolname, temp, i); tool.toolname[i] = 0; } sscanf( &temp[i], "%d%lf", &tool.quantity, &tool.cost); printf( "Name: %s\nQuantity: %d\nCost: %lf\n", tool.toolname, tool.quantity, tool.cost); tool.recordnum = recordnum; }/*end else*/ }
So what happens between the time I enter a new record number and the time I'm supposed to enter data for the record?Press 1 to begin a new file, 2 to use existing data: 1
Enter your choice
1 - store a formatted text file of the inventory called
"storeinv.txt" for printing
2 - update a record
3 - add a new record
4 - delete a record
5 - end program
? 3
Enter new record (1-100): 3
Enter name, quantity, and cost: Name:
Quantity: 0
Cost: 0.000000
Enter your choice
1 - store a formatted text file of the inventory called
"storeinv.txt" for printing
2 - update a record
3 - add a new record
4 - delete a record
5 - end program
?
I have also tried the following:
Code:void eatnewline(void) { int x; do { x = getchar(); } while(x != '\n' && x != EOF); }which is supposed to take care of the newline character. Only this happens when I run the program. I can't figure it out.Code:void newrecord(FILE *fptr) { struct inventory tool = {0, "", 0, 0.0}; int recordnum, tmprcd, i = 0; char temp[30]; printf("Enter new record (1-100): "); scanf("%d", &recordnum); tmprcd = recordnum; fseek(fptr, (recordnum - 1) * sizeof(struct inventory), SEEK_SET); fread(&tool, sizeof(struct inventory), 1, fptr); if(tool.recordnum != 0){ printf("Record #%d already contains information.\n", tool.recordnum); } else{ printf("Enter name, quantity, and cost: "); eatnewline(); fgets( temp, 30, stdin ); while(temp[i] != 0 && !isdigit(temp[i + 1])){ ++i; strncpy(tool.toolname, temp, i); tool.toolname[i] = 0; } sscanf( &temp[i], "%d%lf", &tool.quantity, &tool.cost); printf( "Name: %s\nQuantity: %d\nCost: %lf\n", tool.toolname, tool.quantity, tool.cost); tool.recordnum = tmprcd; }/*end else*/ }
Press 1 to begin a new file, 2 to use existing data: 1
Enter your choice
1 - store a formatted text file of the inventory called
"storeinv.txt" for printing
2 - update a record
3 - add a new record
4 - delete a record
5 - end program
? 3
Enter new record (1-100): 3
Enter name, quantity, and cost: Electric sander 7 57.98
Name: Electric sander
Quantity: 7
Cost: 57.980000
Enter your choice
1 - store a formatted text file of the inventory called
"storeinv.txt" for printing
2 - update a record
3 - add a new record
4 - delete a record
5 - end program
? 2
Enter record to update(1-100): 3
Record has no information.
Enter your choice
1 - store a formatted text file of the inventory called
"storeinv.txt" for printing
2 - update a record
3 - add a new record
4 - delete a record
5 - end program
?
Sorry, I forgot the code to write the new data into the file. It works now.