Parsing file into an array [duplicate] - c

This question already has an answer here:
what's the preferred library for CSV parsing/writing in C++? [closed]
(1 answer)
Closed 7 years ago.
Good day. Don't know whether this question has been asked before. Any who, I have a text file with contents like below
AP0003;Football;13.50;90
AP0004;Skateboard;49.90;30
It is basically,
Item Code;Item Name;Price per unit;Quantity
I am trying to put the contents of the text file into an array but I've had no luck so far. And, I can't find anything similar on Stack Overflow (or maybe my search parameters is not accurate). Would appreciate any help I can get. Am new to C Programming.

Firstly open the file using fopen:
FILE* fp = fopen("NAME_OF_FILE.txt", "r"); // "r" stands for reading
Now, check if it opened
if(fp == NULL) //If fopen failed
{
printf("fopen failed to open the file\n");
exit(-1); //Exit program
}
Suppose that these are your arrays to store the line and each data are:
char line[2048]; //To store the each line
char itemCode[50];
char item[50];
double price;
int quantity; //Variables to store data
Read the file using fgets. It consumes line by line. Put it in a loop which terminates when fgets returns NULL to scan the whole file line by line. Then extract data from the scanned line using sscanf. It, in this case, will return 4 if successful:
while(fgets(line, sizeof(line), fp) != NULL) //while fgets does not fail to scan a line
{
if(sscanf(line, "%[^;];%[^;];%lf;%d", itemCode, item, price, quantity) != 4) //If sscanf failed to scan everything from the scanned line
//%[^;] scans everything until a ';'
//%lf scans a double
//%d scans an int
//Better to use `"%49[^;];%49[^;];%lf;%d"` to prevent buffer overflows
{
printf("Bad line detected\n");
exit(-1); //Exit the program
}
printf("ItemCode=%s\n", itemCode);
printf("Item=%s\n", item);
printf("price=%f\n", price);
printf("Quantity=%d\n\n", quantity); //Print scanned items
}
Finally, close the file using fclose:
fclose(fp);

You can try this code :
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str1[1000],ch;
int i=0;
FILE *fp;
fp = fopen ("file.txt", "r"); //name of the file is file.txt
while(1)
{
fscanf(fp,"%c",&ch);
if(ch==EOF) break; //end of file
else str[i++]=ch; //put it in an array
}
fclose(fp);
return(0);
}
This will put your entire file into an array str including '\n' and other special characters.If you dont want the special characters put neccessary conditions in the while loop.

Related

Check multiple files with "strstr" and "fopen" in C

Today I decided to learn to code for the first time in my life. I decided to learn C. I have created a small program that checks a txt file for a specific value. If it finds that value then it will tell you that that specific value has been found.
What I would like to do is that I can put multiple files go through this program. I want this program to be able to scan all files in a folder for a specific string and display what files contain that string (basically a file index)
I just started today and I'm 15 years old so I don't know if my assumptions are correct on how this can be done and I'm sorry if it may sound stupid but I have been thinking of maybe creating a thread for every directory I put into this program and each thread individually runs that code on the single file and then it displays all the directories in which the string can be found.
I have been looking into threading but I don't quite understand it. Here's the working code for one file at a time. Does anyone know how to make this work as I want it?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
//searches for this string in a txt file
char searchforthis[200];
//file name to display at output
char ch, file_name[200];
FILE *fp;
//Asks for full directory of txt file (example: C:\users\...) and reads that file.
//fp is content of file
printf("Enter name of a file you wish to check:\n");
gets(file_name);
fp = fopen(file_name, "r"); // read mode
//If there's no data inside the file it displays following error message
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
//asks for string (what has to be searched)
printf("Enter what you want to search: \n");
scanf("%s", searchforthis);
char* p;
// Find first occurrence of searchforthis in fp
p = strstr(searchforthis, fp);
// Prints the result
if (p) {
printf("This Value was found in following file:\n%s", file_name);
} else
printf("This Value has not been found.\n");
fclose(fp);
return 0;
}
This line,
p = strstr(searchforthis, fp);
is wrong. strstr() is defined as, char *strstr(const char *haystack, const char *needle), no file pointers in it.
Forget about gets(), its prone to overflow, reference, Why is the gets function so dangerous that it should not be used?.
Your scanf("%s",...) is equally dangerous to using gets() as you don't limit the character to be read. Instead, you could re-format it as,
scanf("%199s", searchforthis); /* 199 characters + \0 to mark the end of the string */
Also check the return value of scanf() , in case an input error occurs, final code should look like this,
if (scanf("%199s", searchforthis) != 1)
{
exit(EXIT_FAILURE);
}
It is even better, if you use fgets() for this, though keep in mind that fgets() will also save the newline character in the buffer, you are going to have to strip it manually.
To actually perform checks on the file, you have to read the file line by line, by using a function like, fgets() or fscanf(), or POSIX getline() and then use strstr() on each line to determine if you have a match or not, something like this should work,
char *p;
char buff[500];
int flag = 0, lines = 1;
while (fgets(buff, sizeof(buff), fp) != NULL)
{
size_t len = strlen(buff); /* get the length of the string */
if (len > 0 && buff[len - 1] == '\n') /* check if the last character is the newline character */
{
buff[len - 1] = '\0'; /* place \0 in the place of \n */
}
p = strstr(buff, searchforthis);
if (p != NULL)
{
/* match - set flag to 1 */
flag = 1;
break;
}
}
if (flag == 0)
{
printf("This Value has not been found.\n");
}
else
{
printf("This Value was found in following file:\n%s", file_name);
}
flag is used to determine whether or not searchforthis exists in the file.
Side note, if the line contains more than 499 characters, you will need a larger buffer, or a different function, consider getline() for that case, or even a custom one reading character by character.
If you want to do this for multiple files, you have to place the whole process in a loop. For example,
for (int i = 0; i < 5; i++) /* this will execute 5 times */
{
printf("Enter name of a file you wish to check:\n");
...
}

data written to txt file appears in some bizzare language[C]

So I've written a program that will take in a information about a dvd (specifically it's postion, IDkey(just some random number) Title, Genre and Year of release), and using a struct it will write that info to a .txt file called "person.txt". I'm positive my code works for the most part but when I go to test it the output received in the .txt file is written in some weird symbol language and not English and quite frankly I have no idea as to why this is. Any explanation on why this is happening would be much appreciated, thanks :)
PROGRAM
#include <stdio.h>
#include <stdlib.h>
// a struct to read and write
struct dvd
{
int fposition;
int fIdKey;
char ftitle[50];
char fgenre[50];
int fyear;
};
int main ()
{
FILE *outfile;
struct dvd input;
// open file for writing
outfile = fopen ("person.txt", "w");
if (outfile == NULL)
{
fprintf(stderr, "\nError opend file\n");
exit (1);
}
printf("Postion: ");
scanf("%d", &input.fposition);
printf("ID Key: ");
scanf("%d", &input.fIdKey);
printf("Title: ");
scanf("%s",&input.ftitle);
printf("Genre: ");
scanf("%s", &input.fgenre);
printf("Year: ");
scanf("%d", &input.fyear);
// write struct to file
fwrite (&input, sizeof(struct dvd), 1, outfile);
if(fwrite != 0)
printf("contents to file written successfully !\n");
else
printf("error writing file !\n");
// close file
fclose (outfile);
return 0;
}
TEST RUN
TEST RUN OUTPUT IN THE .TXT FILE
You are writing these values to the file:
int fposition;
int fIdKey;
char ftitle[50];
char fgenre[50];
int fyear;
But you are displaying the whole file as characters. That kind of works for ftitle and fgenre because they really are characters...though since you don't populate all 50 characters there are some ugly uninitialized characters shown as well. That is easy to fix: just fill the unused characters (as well as the null terminator) with some known character (such as space) before writing to the file, or do not write the unused characters at all. You can use strlen() to find the length of each string and memset() to set the unused characters to a well-known character which is printable.
Next, saving an int and reading it as text is problematic. You need to decide on a single format. Either you write as integers like now, and you read as integers (which means you need a special program to read the file), or you commit to writing only text to the file.
Easiest might be to only write text to the file. You can use fprintf() for that, instead of fwrite(). You can use fprintf() for the character arrays as well, it will automatically write only the "used" part of each string up to the null terminator, skipping all the "garbage" characters.

how to count the number of rows present in the file using C [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I have designed a program in c program to count the number of rows but it shows the garbage values.
My file contains the data as follows
2,8,10
3,5,7
4,5,1
3,6,8
3,7,8
3,8,4
for counting the number of rows i have written the program as
int count_lines =0;
char sample_char;
FILE *fptr;
fptr = fopen("demo3.txt", "r");
sample_chr = getc(fptr);
while (sample_chr != EOF)
{
if (sample_chr == '\n')
count_lines = count_lines +1;
sample_chr = getc(fptr);
}
printf("\n\n\n The number of lines are %d",count_lines);
but the garbage values are being printed here. Where i am going wrong???
when i am writing the below code it works perfectly
typedef struct ratings {
int userId;
int movieId;
int rating;
}Ratings;
int i, n=65;
FILE *fptr;
fptr = fopen("demo3.txt", "r");
/* *//counting the number of lines present in the above file
sample_chr = getc(fptr);
while (sample_chr != EOF)
{
if (sample_chr == '\n')
count_lines = count_lines +1;
sample_chr = getc(fptr);
}* */
printf("\n\n\n The number of lines are %d",count_lines);
//storing the values in array of structures
for(i=0;i<n;i++)
fscanf(fptr, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating);
now if i am printing the contents i am getting the output. If i remove the comment lines then garbage value appears
You forgot to check whether the file opened.
fptr = fopen("demo3.txt", "r");
Every file operation, especially opening a file, should be error checked. Here's an example.
#include <stdio.h>
#include <string.h>
#inculde <errno.h>
...
char filename[] = "demo3.txt";
FILE *fptr = fopen(filename, "r");
if( fptr == NULL ) {
fprintf( stderr, "Could not open %s for reading: %s\n",
filename, strerror(errno)
);
exit(1);
}
//storing the values in array of structures
for(i=0;i<n;i++)
fscanf(fptr, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating);
This would be what is producing the garbage. Because it comes after getc is done reading the file, calls to fscanf will try to read past the end of the file and fail (again, check every file operation). Nothing will be put into REC1, it will contain the garbage it had when it was declared.
Think of fptr like a cursor in an editor. Every time you read from it, the cursor moves forward. Every call to getc moves the cursor forward one character. By the time you call fscanf, it's reached the end of the file.
You can move the cursor around with fseek. Use it to move fptr back to the beginning of the file. And, yup, check to make sure it worked.
if( fseek(fptr, 0, SEEK_SET) != 0 ) {
fprintf( stderr, "Could not rewind %s: %s\n", filename, strerror(errno) );
}
Note that you'll still get garbage because you're reading n times rather than count_lines times.
Note that you can't display the offending line. This, and many other reasons, is why it's best to avoid fscanf and instead read the line with fgets and use sscanf to parse the line. This also does away with the need to read n times, just read until all the lines are done.
// A line buffer
char line[1024];
int i = 0;
// Read a line
while( fgets( line, sizeof(line), fptr) != NULL ) {
// Parse the line
if( sscanf(line, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating) < 3 ) {
fprintf( stderr, "Could not understand '%s' from %s\n", line, filename );
continue;
}
// Print what we got
printf("uid: %d, mid: %d, rating: %d\n", REC1[i].userId, REC1[i].movieId, REC1[i].rating);
i++;
}
As for making sure REC1 is big enough to hold all the lines, look into realloc.
after walking through the file, counting the number of lines,
Then need to rewind() or lseek() the file back to the beginning before extracting the data

Making Input and Output files in C language according to the code?

This is a first formal C competition I am going through .In the last years paper they had- Specified something called aromatic number and told to find those .I wrote the code and it works well but I am not able to understand these instructions about input and output and how to code them in C for Windows.
I am aware about reading one letter from a file and writing it using fopen() and fprintf and fscanf. But these are letters written in different lines how to extract them as variables from in1.dat and print them in out1.dat?
Means I know
int main()
{
int n;
FILE *fptr;
if ((fptr=fopen("D:\\program.dat","r"))==NULL){
printf("Error! opening file");
exit(1); /* Program exits if file pointer returns NULL. */
}
fscanf(fptr,"%d",&n);
printf("Value of n=%d",n+n);
fclose(fptr);
getch();
}
Which scans the first value in the 1st line .But they ask for multiple lines(3 in sample input) how to do them?
fscanf(fptr,"%d",&n);
printf("Value of n=%d",n+n);
Instead do like this -
while(fscanf(fptr,"%d",&n))
{
printf("Value of n=%d",n+n); //But notice here with every iteration n will be over-written.
}
This will stop at the first conversion failure or end of the file.And then inside this loop you can write into output file .
Try Something Like This:
#include<stdio.h>
int main()
{
FILE *in,*out;
int num;
char line[512],aronum[20];
in = fopen("in.dat", "r");
out = fopen("out.dat","w");
fgets(line, 512, in); //to get number of test cases
sscanf (line, "%d",&num);
while((fgets(line, 512, in) != NULL) && (num--))
{
sscanf (line, "%s",&aronum);
fprintf(out,"%d",calc(aronum)); //use `calc` func to return int ans.
}
fclose(in);
fclose(out);
return 0;
}

fgets Introducing new line in user's input [duplicate]

This question already has answers here:
Removing trailing newline character from fgets() input
(14 answers)
Closed 8 years ago.
I'm prompting the user for the file name, but once the user presses enter, it takes that into the file name as well. so the file is never found.
int main (){
char file[100];
FILE *fp;
printf("Please enter a valid filename:\n");
fgets(file,100,stdin);
fp=fopen(file, "r");
if(!fp){
printf("File not found.\n"); \\This will always happen because a new line is added to the user's input.
return 1;}
If I use
scanf("%s", file);
The issue doesn't happen, but I heard scanf is not a good function to use and would introduce new issues. How can I solve the new line problem with fgets?
After fgets(file,100,stdin);, do this file[strlen(file)-1]='\0';, it will remove \n from the code. To use strlen() function you need to include string.h in your code.
Try this modified code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (){
char file[100];
FILE *fp;
printf("Please enter a valid filename:\n");
fgets(file,100,stdin);
file[strlen(file)-1]='\0'; //Removing \n from input
fp=fopen(file, "r");
if(fp==NULL)
{
printf("File not found.\n");
return 1;
}
else
{
printf("File found!\n");
fclose(fp);
return 0;
}
}
fgets() returns the \n new line code.... that's what it does. You must wipe out that character.
Given that overflowing, or at least totally filling, incoming buffers is a popular attack vector I prefer code that defends against such.
char *cp;
file[(sizeof file)-1)] = '\0'; /* assure \0 termination on buffer fill attack */
cp = strchr( file, '\n' ); /* find expected \n, but allow for none */
if ( cp ) *cp = '\0'; /* safely clear closing \n */

Resources