Make array read file and store all data - c

Okay, so all my code is functional. I am mostly looking for suggestions.
Right now, I have a file being read. Each line of the file has 3 different variables. These variables are being read into an array.
The problem I am trying get input on it that as the file is read in the while loop, the data overwrites itself. I need all the data stored in one array with spaces between. I a not sure what it is not currently doing that. Is there a better function to be using?
Here is a sample of what I have:
char filepath[1000], filepathBP1[1000];
char BP2_ext [] = "\\BP_2.txt";
char bp2_Val1[80], bp2_Val2[80], bp2_Val3[80], bp2_Line[100];
FILE* fp;
strcpy(filepathBP1, filepath);
strcat(filepathBP1, BP1_ext);
fp = fopen(filepathBP1, "r");
if (fp == NULL)
{
puts("ERROR OPENING FILES");
exit(EXIT_FAILURE);
}
while (!feof(fp))
{
printf("\n\nREADING BP_1.txt...");
fgets(bp1_Line, 100, fp);
sscanf(bp1_Line, "%s\t%s\t%s", bp1_Val1, bp1_Val2, bp1_Val3);
printf("%s\t%s\t%s\n", bp1_Val1, bp1_Val2, bp1_Val3);
}
fclose(fp);

Here is a modified version of your code. Note this is just a basic solution. Please feel free to modify the code according to your needs. Now your basic idea/approach is correct. The only thing you need to do is that you have to have an array of "Strings" to store the "strings". Also, your question isn't clear. Please be more specific as to what you finally want the output to result in or look like.
Now in my program I have 3 array of "strings" variables. And each of these store the strings of a column of strings.
For example if the file data is like this,
abc def zxc
qwe rty uio
Then line_list1 will store strings abc,qwe, line_list2 will store the strings def,rty and line_list3 will store the strings zxc,uio. Now I don't know if this exactly what you want(since you haven't been specific what the resulting output should be/do/look like.), but, this program will give you an idea to make your program work.
Here is the program,
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100
int main(){
char bp1_Line[MAX];
char *line_list1[MAX],*line_list2[MAX],*line_list3[MAX];
int index=0,i=0;
FILE* fp=NULL;
fp = fopen("data.txt", "r");
if (fp == NULL){
puts("ERROR OPENING FILES");
exit(EXIT_FAILURE);
}
while ( fgets(bp1_Line, MAX, fp)!= NULL && index<MAX){
printf("READING:%s\n",bp1_Line);
if(sscanf(bp1_Line, "%s\t%s\t%s", &line_list1[index], &line_list2[index], &line_list3[index]) == 3){
strcpy(bp1_Line,"");
index++;
}
}
fclose(fp);
for(i=0;i<index;i++){
printf("%s\t%s\t%s\n", &line_list1[i], &line_list2[i], &line_list3[i]);
}
return 0;
}
Or if you wanna store all those strings/words in one array of strings then change the above code while loop section to this code,
while ( fgets(bp1_Line, MAX, fp)!= NULL && index<MAX){
printf("READING:%s\n",bp1_Line);
if(sscanf(bp1_Line,"%s\t%s\t%s",&list[index],&list[index+1],&list[index+2]) == 3){
strcpy(bp1_Line,"");
index=index+3;
}
}

You should switch to another programming language. Python may be good for you.
You left out most of the error handling. Python will throw exceptions in such a case, which are hard to ignore.
You use fixed-length character arrays without checking for overflow. Python has built-in string support.
Python has built-in support for data structures like resizable sequences and even dictionaries.

Related

Finding a keyword from one file in another file

So my project for class needs me to find a list of keywords from one file:
Master's,Bachelor's,Professor
And needs me to find it through a resume in another file:
John Smith
1234 Residence Road
johnsmith#gmail.com
Degree level: Bachelor's degree
Major: Applied mathematics
Work Experience:
Professor at local university for multiple math classes, mainly calculus
Worked at a tech company studying the analytics of their online store
Now I have the keywords stored in an array of char spacing[10][15] (with no commas)
and I have the resume saved as char* buffer. Both work, as they both print out, but when trying to find the keywords I keep getting 0 (int KWcount is the counter for the amount of times a keyword appears). Here's the code both putting the resume into buffer and my attempt at finding the words.
//Resume
FILE* fp2;
fp2 = fopen("resume.txt", "r");
if (fp == NULL) {
printf("\nFile not found.\n");
return 0;
}
//File Reading
fseek(fp2, 0L, SEEK_END);
numbytes = ftell(fp2);
fseek(fp2, 0L, SEEK_SET);
buffer = (char*)calloc(numbytes, sizeof(char));
if (buffer == NULL)
return 1;
fread(buffer, sizeof(char), numbytes, fp2);
fclose(fp2);
printf("Before process: %i", KWcount);
//Search for keyword
for (i=0; i < 10; i++) {
if (strcmp(buffer, spacing[i]) == 0) {
KWcount++;
}
}
printf("\n\nAfter process:%i\n", KWcount);
fclose(fp2);
}
Before process:0
After process:0
I genuinely cannot figure out what the problem is and my professor is not really any help, so does anyone have any tips or ways to fix this?
strcmp(buffer, spacing[i])
strcmp will return 0 only if the two arguments point to strings which are exactly equal. What you need to do is search buffer word by word and then compare those with the word you expect to find.
You may find the function strtok useful to break apart your resume buffer into words.
And also I recommend using strncmp, since it allows you to cap the maximum number of characters in your comparison. After all, your goal is to compare just a single word from the resume, not the entire string.

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;
}

Parsing file into an array [duplicate]

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.

Trouble testing copy file function in C

Okay so this is probably has an easy solution, but after a bit of searching and testing I remain confused.. :(
Here is a snippet of the code that I have written:
int main(int argc, char *argv[]){
int test;
test = copyTheFile("test.txt", "testdir");
if(test == 1)
printf("something went wrong");
if(test == 0)
printf("copydone");
return 0;
}
int copyTheFile(char *sourcePath, char *destinationPath){
FILE *fin = fopen(sourcePath, "r");
FILE *fout = fopen(destinationPath, "w");
if(fin != NULL && fout != NULL){
char buffer[10000];//change to real size using stat()
size_t read, write;
while((read = fread(buffer, 1, sizeof(buffer), fin)) > 0){
write = fwrite(buffer, 1, read, fout);
if(write != read)
return 1;
}//end of while
}// end of if
else{
printf("Something wrong getting the file\n");
return 0;}
if(fin != NULL)
fclose(fin);
if(fout != NULL)
fclose(fout);
return 0;
}
Some quick notes: I am very new to C, programming, and especially file I/O. I looked up the man pages of fopen, fread, and fwrite. After looking at some example code I came up with this. I was trying to just copy a simple text file, and then place it in the destination folder specified by destinationPath.
The folder I want to place the text file into is called testdir, and the file I want to copy is called test.txt.
The arguments I have attempted to use in the copyFile function are:
"test.txt" "testdir"
".../Desktop/project/test.txt" ".../Desktop/project/testdir"
"/Desktop/project/test.txt" "/Desktop/project/testdir"
I just get the print statement "Something wrong getting the file" with every attempt. I am thinking that it may be because 'testdir' is a folder not a file, but then how would I copy to a folder?
Sorry if this a really basic question, I am just having trouble so any advice would be awesome!
Also, if you wanted to be extra helpful, the "copyTheFile" function is supposed to copy the file regardless of format. So like if its a .jpg or something it should copy it. Let me know if any of you guys see a problem with it.
This is with ISO/POSIX/C89/C99 on Linux.
At the start, you'll want to include stdio.h to provide FILE and the I/O function declarations:
#include <stdio.h>
Aside from this, your program compiles and works properly for me. Unfortunately you can't copy to a directory without using stat() to detect if the destination is a directory, and if so, appending a file name before opening the file.
Some other minor suggestions:
A buffer with a power of two bytes such as 4096 is probably more efficient due to it lining up with filesystem and disk access patterns
Conventionally, C functions that return a status code use 0 for success and other values such as 1 for failure, so swapping your return values may be less confusing
When a standard library function such as fopen, fread or fwrite fails, it is a good idea to use perror(NULL); or perror("error prefix"); to report it, which may look something like:
$ ./a.out
...
error prefix: No such file or directory
if you are trying to write a new file in a directory, you should be giving the full path of the file to be written. in your case
"C:...\Desktop\project\testdir\testfile"

C, reading a multiline text file

I know this is a dumb question, but how would I load data from a multiline text file?
while (!feof(in)) {
fscanf(in,"%s %s %s \n",string1,string2,string3);
}
^^This is how I load data from a single line, and it works fine. I just have no clue how to load the same data from the second and third lines.
Again, I realize this is probably a dumb question.
Edit: Problem not solved. I have no idea how to read text from a file that's not on the first line. How would I do this? Sorry for the stupid question.
Try something like:
/edited/
char line[512]; // or however large you think these lines will be
in = fopen ("multilinefile.txt", "rt"); /* open the file for reading */
/* "rt" means open the file for reading text */
int cur_line = 0;
while(fgets(line, 512, in) != NULL) {
if (cur_line == 2) { // 3rd line
/* get a line, up to 512 chars from in. done if NULL */
sscanf (line, "%s %s %s \n",string1,string2,string3);
// now you should store or manipulate those strings
break;
}
cur_line++;
}
fclose(in); /* close the file */
or maybe even...
char line[512];
in = fopen ("multilinefile.txt", "rt"); /* open the file for reading */
fgets(line, 512, in); // throw out line one
fgets(line, 512, in); // on line 2
sscanf (line, "%s %s %s \n",string1,string2,string3); // line 2 is loaded into 'line'
// do stuff with line 2
fgets(line, 512, in); // on line 3
sscanf (line, "%s %s %s \n",string1,string2,string3); // line 3 is loaded into 'line'
// do stuff with line 3
fclose(in); // close file
Putting \n in a scanf format string has no different effect from a space. You should use fgets to get the line, then sscanf on the string itself.
This also allows for easier error recovery. If it were just a matter of matching the newline, you could use "%*[ \t]%*1[\n]" instead of " \n" at the end of the string. You should probably use %*[ \t] in place of all your spaces in that case, and check the return value from fscanf. Using fscanf directly on input is very difficult to get right (what happens if there are four words on a line? what happens if there are only two?) and I would recommend the fgets/sscanf solution.
Also, as Delan Azabani mentioned... it's not clear from this fragment whether you're not already doing so, but you have to either define space [e.g. in a large array or some dynamic structure with malloc] to store the entire dataset, or do all your processing inside the loop.
You should also be specifying how much space is available for each string in the format specifier. %s by itself in scanf is always a bug and may be a security vulnerability.
First off, you don't use feof() like that...it shows a probable Pascal background, either in your past or in your teacher's past.
For reading lines, you are best off using either POSIX 2008 (Linux) getline() or standard C fgets(). Either way, you try reading the line with the function, and stop when it indicates EOF:
while (fgets(buffer, sizeof(buffer), fp) != 0)
{
...use the line of data in buffer...
}
char *bufptr = 0;
size_t buflen = 0;
while (getline(&bufptr, &buflen, fp) != -1)
{
...use the line of data in bufptr...
}
free(bufptr);
To read multiple lines, you need to decide whether you need previous lines available as well. If not, a single string (character array) will do. If you need the previous lines, then you need to read into an array, possibly an array of dynamically allocated pointers.
Every time you call fscanf, it reads more values. The problem you have right now is that you're re-reading each line into the same variables, so in the end, the three variables have the last line's values. Try creating an array or other structure that can hold all the values you need.
The best way to do this is to use a two dimensional array and and just write each line into each element of the array. Here is an example reading from a .txt file of the poem Ozymandias:
int main() {
char line[15][255];
FILE * fpointer = fopen("ozymandias.txt", "rt");
for (int a = 0; a < 15; a++) {
fgets(line[a], 255, fpointer);
}
for (int b = 0; b < 15; b++) {
printf("%s", line[b]);
}
return 0;
This produces the poem output. Notice that the poem is 14 lines long, it is more difficult to print out a file whose length you do not know because reading a blank line will produce the output "x�oA". Another issue is if you check if the next line is null by writing
while (fgets(....) != NULL)) {
each line will be skipped. You could try going back a line each time to solve this but i think this solution is fine for all intents.
I have an even EASIER solution with no confusing snippets of puzzling methods (no offense to the above stated) here it is:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string line;//read the line
ifstream myfile ("MainMenu.txt"); // make sure to put this inside the project folder with all your .h and .cpp files
if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
cout << line << endl;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
Happy coding

Resources