How to read data from a text file - c

How do I read input from my text file? The input file is several lines long, and each line is of the format city city distance where there are two cities and the distance between them.
I have tried several things to read the input, but unfortunately those did not work. I need
to parse the individual values on each line. (Each line consists of 2 city names and the distance between them.) Any help would be appreciated.
data = fopen(argv[1],"r");
while(!EOF){
while(1){
c=fgetc(data);
inname=(char**)malloc(sizeof(char*));
if(c==' ')
mode++;
else if(c=='\n'){mode=0;
break;}
else {
switch(mode%3){
case 0;
for(i=0;fgetc(data)!=' ';i++){
if(inname[count]!=NULL) {count++;inname=(char**)malloc(sizeof(char*));}
inname[count][i]=fgetc(data);}
break;
case 1;
if(inname[count]!=NULL){ count++;inname=(char**)malloc(sizeof(char*));}
for(i=0;fgetc(data)!=' ';i++){
inname[count][i]=fgetc(data);}
break;
/*case 2;for(i=0;fgetc(data)!='\n';i++){
dist[say]=atoi(str);}}}*/
}}}count++;}
`

I think you should look into fscanf for reading formatted input like this.
To read a line containing two strings and an int, you would have something like:
fscanf(data, "%s %s %d", &city1, &city2, &distance);
To read multiple lines until EOF, your code should be of the following form:
while(fscanf(data, "%s %s %d", &city1, &city2, &distance)!=EOF) {
/* rest of your logic here */
}

Related

Search for word within file and display the title of the section containing the word?

I have to search for a word from a file containing multiple songs, separated by a specific string, and display every song title that contains the word in its lyrics.
The file has the following format:
xxxxxxxxxx
song title
Lyrics
xxxxxxxxxx
Song Title
Lyrics
[...]
The code I wrote is:
#include <stdio.h>
#include<string.h>
/* Note: pif will be function needed to search a word within a generic string */
int main(){
FILE *fp=fopen("file.txt", "r");
char line[200],search_string[]="xxxxxxxxxx",word[20],buff[200];
int cnt=0,flag=0;
gets(word);
if (!fp)
return -1;
printf("\n\tSongs Containing %s: ", word);
cnt=0;
while ( fgets ( line, 200, fp ) != NULL ) /*read a line*/
{
if(strstr(line,search_string)){ /*find the separator*/
fgets(line,200,fp);/*go ahead reading*/
strcpy(buff,line); /*save the title, which is the very next line after the separator*/
while(!strstr(line,search_string)){ /* while the lyrics do not match with another
separator go ahead reading*/
fgets(line,200,fp);
if(pif(line,word)) /*using the defined *pif* function (required), I'd find *word*
within the line */
flag=1;
}
if(flag)
printf("%s", buff);
}
}
fclose(fp);
return 1;
}
Is there anyway I can make this whole stuff working? The output displays each song titles instead of specific ones.
if(flag) printf("%s", buff); break; this should break after printing the very first song, but you're saying it's not.. so I think you've a typo in post..
now your code.. After you set your flag to 1 after you found a match, then you are not setting it back to zero even after printing the string. As your inner while iterates through the complete song, the print is done at the start of next song, where you should set flag=0; or else even if that word is not in the song, as flag remains 1, the song name is printed.
if(flag)
{
printf("%s", buff);
flag=0;
}
This should work.
note: all of this assumes your pif function is working properly.
Its just an issue of not resting your flag to 0 before your next check. Right now, every title that occurs after the first song that has the matching world will be printed. If your problem still persists it might have something to do with the pif function. Please do share if you do not get this right !!

How do I read a text file and store it in an array in C programming (values seperated by a comma)?

I need help with getting datapoints, x and y values from a txt file into two arrays.
Currently, the text file consists of 5 lines like:
0.116
0.118
0.12
0.122
0.124
This is my code:
#include <stdio.h>
#include <stdlib.h>
main(void)
{
FILE *inp; /* pointer to input file */
double item;
int cnt=0,y,d,i;
double array[300],swap;
/* Prepare files for input */
inp = fopen("testdoc.txt", "r");
/* Read each item */
while ( (fscanf(inp, "%lf", &item) == 1) && (!feof(inp)) ) {
array[cnt] = item;
cnt++;
}
for (int i = 0; i < cnt; i++)
{
printf("%lf\n",array[i]);
}
printf("The total number of inputs is %d",cnt);
fclose(inp); /* Close the files */
return (0);
}
This only reads the first half of the file, which are the x values. Of which output is
0.116000
0.118000
0.120000
0.122000
The total number of inputs is 4
However, I want to read a text file and store the values in two different arrays for x and y values.
The new text file will look like this
0.116,-0.84009
0.118,4.862
0.12,-1.0977
0.122,0.22946
0.124,3.3173
How do i go changing my code above to recognize the Y values after "," sign? And to add both into two arrays at once?
I tried compiling your code posted on pastebin and received an error because of a missing bracket in your while statement.
That's an easy fix.
The larger issue is in the condition of the while loop.
fscanf returns the number of input items converted and assigned on each call.
When you modified your code to return two values, the condition in the while loop fscanf(inp, "%lf,%lf", &v1,&v2) == 1 would fail and the loop will not be entered.
Please modify the while statement to (have included the missing "(" too)..
while ( (fscanf(inp, "%lf, %lf", &v1, &v2) == 2) && (!feof(inp)) )
and you should be good to go!!!
In addition it would be a good practice to include the return type of int for the main function.

detect if a line is match to a format - in C

I have a file and I need to check if its lines are in the following format:
name: name1,name2,name3,name4 ...
(some string, followed by ":", then a single space and after that strings separated by ",").
I tried doing it with the following code:
int result =0;
do
{
result =sscanf(rest,"%[^:]: %s%s", p1,p2,p3);
if(result==3)
{
printf("invalid!");
fclose(fpointer);
return -1;
}
}while (fgets(rest ,LINE , fpointer) != NULL);
this works good for lines like: name: name1, name2 (with space between name1, and name2).
but it fails with the following line:
name : name1,name2
I want to somehow tell sscanf not to avoid this white space before the ":".
could someone see how ?
Thanks for helping!
This works for me:
result = sscanf(rest,"%[^*:]: %[^,],%s", p1, p2, p3);
Notice the * is used to consume the space (if any).

How to open a file with a user inputted variable in C?

I'm writing a POS program as a school assignment. I'm using multiple txt files as a database. The program is suppose to allow the user to enter a SKU number (e.g. 123) then it will open a txt file in a database (e.g. database/123.txt). It then pull info from the txt file such as a price and allow the user to add multiple files and end with a total. The user can also add to the database by creating new SKUs. They are also able to view transaction history. The issue I am having is I can't seem to figure out how to record a number from a user and then use that number to open a text file beginning with that number. (e.g. use enters 123 then 123.txt is opened.)
Here is the section of my code that I need help with:
// Function to start a transaction
int transaction(void)
{
// Define Variables
char buf[1000], nDatabase[100];
float nPrice[500], nTotal;
// Instructions
printf("You have started a transaction.\n");
printf("Enter the SKU number below.\n");
printf("Enter 0 to complete the transaction.\n");
// Begin loop here
do
{
FILE *ptr_file;
// record SKU number
/*remove test tools later*/
printf("we r here\n");
scanf("Enter the SKU: %c\n", &nDatabase);
printf("now we r here\n");
// Open database file
/*Change location later*/
ptr_file = fopen("database/123.txt", "r");
// If file is not found return 1
if (!ptr_file)
{
printf("Could not match that SKU number.\n");
return 1;
}
while (fgets(buf, 1000, ptr_file) != NULL)
printf("%s\n", buf);
scanf("%s", &nPrice[0]);
// Close file
fclose(ptr_file);
while (nDatabase == 0);
nTotal = nPrice[0] + nPrice[1];
printf("Your total is: $%.2f\n", &nTotal);
return 0;
}
}
printf( "Enter the SKU: " ) ; // <-- scanf if only for input, the prompt must be output separately
scanf( "%s\n", nDatabase);
// ^ ^
// | |_No & here - nDatabase is an array
// |
// |_Accept a string not a character
Then you might form a complete file name with sprintf, e.g.
char filename[MAX_FNAME] ;
sprintf( filename, "database/%s,txt", nDatabase ) ;
Be aware that no error checking or overrun protection is performed by the above - you may want to consider adding some.
You need to concatenate the user input with you database path, and extension.
Check this post: C string append

Why does my program read an extra structure?

I'm making a small console-based rpg, to brush up on my programming skills.
I am using structures to store character data. Things like their HP, Strength, perhaps Inventory down the road. One of the key things I need to be able to do is load and save characters. Which means reading and saving structures.
Right now I'm just saving and loading a structure with first name and last name, and attempting to read it properly.
Here is my code for creating a character:
void createCharacter()
{
char namebuf[20];
printf("First Name:");
if (NULL != fgets(namebuf, 20, stdin))
{
char *nlptr = strchr(namebuf, '\n');
if (nlptr) *nlptr = '\0';
}
strcpy(party[nMember].fname,namebuf);
printf("Last Name:");
if (NULL != fgets(namebuf, 20, stdin))
{
char *nlptr = strchr(namebuf, '\n');
if (nlptr) *nlptr = '\0';
}
strcpy(party[nMember].lname,namebuf);
/*Character created, now save */
saveCharacter(party[nMember]);
printf("\n\n");
loadCharacter();
}
And here is the saveCharacter function:
void saveCharacter(character party)
{
FILE *fp;
fp = fopen("data","a");
fwrite(&party,sizeof(party),1,fp);
fclose(fp);
}
and the loadCharacter function
void loadCharacter()
{
FILE *fp;
character tempParty[50];
int loop = 0;
int count = 1;
int read = 2;
fp= fopen("data","r");
while(read != 0)
{
read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
printf("%d. %s %s\n",count,tempParty[loop].fname,tempParty[loop].lname);
loop++;
count++;
}
fclose(fp);
}
So the expected result of the program is that I input a name and last name such as 'John Doe', and it gets appended to the data file. Then it is read in, maybe something like
1. Jane Doe
2. John Doe
and the program ends.
However, my output seems to add one more blank structure to the end.
1. Jane Doe
2. John Doe
3.
I'd like to know why this is. Keep in mind I'm reading the file until fread returns a 0 to signify it's hit the EOF.
Thanks :)
Change your loop:
while( fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp) )
{
// other stuff
}
Whenever you write file reading code ask yourself this question - "what happens if I read an empty file?"
You have an algorithmic problem in your loop, change it to:
read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
while(read != 0)
{
//read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
printf("%d. %s %s\n",count,tempParty[loop].fname,tempParty[loop].lname);
loop++;
count++;
read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
}
There are ways to ged rid of the double fread but first get it working and make sure you understand the flow.
Here:
read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
printf("%d. %s %s\n",count,tempParty[loop].fname,tempParty[loop].lname);
You are not checking whether the read was successful (the return value of fread()).
while( 1==fread(&tempParty[loop],sizeof*tempParty,1,fp) )
{
/* do anything */
}
is the correct way.
use fopen("data","rb")
instead of fopen("data","r") which is equivalent to fopen("data","rt")
You've got the answer to your immediate question but it's worth pointing out that blindly writing and reading whole structures is not a good plan.
Structure layouts can and do change depending on the compiler you use, the version of that compiler and even with the exact compiler flags used. Any change here will break your ability to read files saved with a different version.
If you have ambitions of supporting multiple platforms issues like endianness also come into play.
And then there's what happens if you add elements to your structure in later versions ...
For robustness you need to think about defining your file format independently of your code and having your save and load functions handle serialising and de-serialising to and from this format.

Resources