strstr C function is functioning abnormally - c

For the C project coming up, the goal is to read in a CSV file with the first two lines listing the row and column lengths like
attributes: 23
lines: 1000
e,x,y,n,t,l,f,c,b,p,e,r,s,y,w,w,p,w,o,p,n,y,p
e,b,y,y,t,l,f,c,b,n,e,c,s,s,w,w,p,w,o,p,n,s,m
e,x,f,y,t,l,f,w,n,w,t,b,s,s,w,w,p,w,o,p,n,v,d
e,s,f,g,f,n,f,c,n,k,e,e,s,s,w,w,p,w,o,p,k,v,u
The thing is, I don't know if future file inputs will be of the same row/column lengths, so I'm implementing a determineFormat function to read those first two lines, which will be used for building the data structures.
In order to do this, I need to match a substring to the current line. If it matches, then fscanf is used to read in the line and extract the length integers. However, this code isn't working, as the entire strstr function is getting skipped over in ddd.
int lineCount, attrCount; //global variables
void determineFormats(FILE *incoming){
char *curLine= emalloc(CLINPUT);
int i;
char *ptr=NULL;
for (i=0; i<2; i++){
if (fgets(curLine, CLINPUT, incoming) != NULL){
ptr= strstr(curLine, "attrib"); //this line is skipped over
if (ptr!= NULL)
fscanf(incoming, "attributes: %d", &attrCount);
else
fscanf(incoming, "lines: %d", &lineCount);
}
}
printf("Attribute Count for the input file is: %d\n", attrCount);
printf("Line count is: %d\n", lineCount);
}
My thinking for the if/else block is since there are only two lines of interest to this function, and they're both at the head of the file, just scan each line and test if the string matches. If it does, then the non-null conditional is run, otherwise the other conditional is executed. However, in this case, the strstr function is getting skipped.
Extra Info
Some of the comments made me go back and double check.
CLINPUT is defined to be 100, or roughly 40% again the number of characters to read from each line.
This is the output from ddd when ptr= strstr(curLine, "attrib"); is called:
0xb7eeaff0 in strstr () from /lib/libc.so.6
Single stepping until exit from function strstr,
which has no line number information.
Once this happens, the line indicator disappears, and single stepping (F5) from that point returns to the calling function.

strstr is working good. Problem is that fscanf will read next line since current already read.
Here's more correct way
for (i=0; i<2; i++){
if (fgets(curLine, CLINPUT, incoming) != NULL){
if (strstr(curLine, "attributes:")) {
sscanf(curLine, "attributes: %d", &attrCount);
} else if (strstr(curLine, "lines:")) {
sscanf(curLine, "lines: %d", &lineCount);
}
}
}

Related

How can i print lines from multiple files sequentially?

I'm trying to write a function that given an array of text files, it prints all lines that share the same index on the same line, for example:
file1:
hey
there
file2:
1
2
output:
hey 1
there 2
I can't seem to find a way of iterating through the lines of all the files like someone would do on an array. This is where i'm stuck at:
void paste(FILE** files,int argc){
int maxLines = getMaxLines(files,argc);
int line = 1;
//char buf[256];
char ch;
for (int i=0; i<maxLines; i++){
for (int j=1; j<argc; j++){
while ((ch=fgetc(files[j])) != '\n'){
putchar(ch);
}
}
printf("\n");
line++;
}
//printf("%d",maxLines);
}
Obviously it doesnt do what is intended but i think i have the main idea captured in that piece of code. How can i use the line index to iterate through lines? How can i access each line this way?
Create a function that prints a line from a file - basically, your while loop (no need for line index, since the position in the file is persistent, meaning that each time you call the function for some file, the next line will be printed).
Now iterate over the files, printing one line from each, again and again, until one of them reaches eof.

How do use fgets to find if this line exists in .csv file? (C)

Hi I'm tyring to use fgets in a C program to see whether or not a name exists in a line in a .csv file. If it does, then it saves it in an array then returns it. Right now, it saves everything line from the .csv file and I'm not sure why.
C file:
void FindRecord(char *filename, char *name, char record[]) {
char *temp = record; //temp save record
FILE *q = fopen(filename, "r"); //check that ths inputed .csv file exists
if (q == NULL ) { //if it doesn't, then print error message and exit
printf("This .csv does not exist");
exit(1); //terminate with error message
}
while(!feof(q)) { //while I'm not at the end of the file
fgets(temp, 1000, q); //Reads a line # a time
for (int i = 0; i < 1000; i++) {
if(temp[i] == *name) {
record[i] = temp[i];
name++;
}
}
printf("%s", record);
}
fclose(q);
}
.csv file:
Kevin, 123-456-7890
Sally, 213-435-6479
Megan, 415-336-8790
Right now whats happening when I run the program is that it returns the 3 lines. I want iso that if *name points to the name "Kevin" and it comes with temp, it'll just return: Kevin, 123-456-7890
Right now whats happening when I run the program is that it returns the 3 lines.
I don't see how that's possible. You have only one array in which to return a result. I could believe that your code prints all three lines, but it will return only the last.
I want iso that if *name points to the name "Kevin" and it comes with temp, it'll just return: Kevin, 123-456-7890
Well, your code has several problems in that regard. Among the most significant are:
Although it performs some character-by-character comparisons, it has no code anywhere to reject lines that fail to match.
It sets temp to point to the same array as record, and then reads each line into that array. This will overwrite that array even in the event that no match is found, and if a match is found on a line other than the last one read then the actual match will be lost.
It modifies the name pointer as it attempts to match, with no mechanism for resetting it in the event of a partial match.
When trying to match the name, it blithely scans past the , delimiter in the input line and, if it comes to them, the string terminators in the name and the input string.
while (!feof(file)) is always wrong.

New to C, trying to better understand char arrays, pointers, reading in files, etc

Alright, so I am working on linux and emacs for the first time using C, and coming from pretty beginner level java programming in eclipse, my new CS course is really daunting. SO much stuff has been thrown at me as if I already knew it...
Anyway, the current part of my assignment I am working on involves reading in text from a file (doing that by piping a text file as standard input into my program). Currently I had three functions, a main function where I read in the file / call other functions, a function that reverses the order of a single word (apple becomes elppa) with *char beg and *char end as parameters, and a function that reverses the order of every word in a line of words, calling the previous function and taking a char *str as a parameter.
I am having trouble reading in the files in my main method in a way that makes it easy to utilize these functions. Here's a snippet of how I am reading them in currently, but as you can see I haven't figured out a way to store a line of words and send that into my function (I need to reverse line by line, so I can't just add every single char to one long array)
enter code here``
char line[8192]
int location = 0;
FILE *in = stdin;
int buff = 0;
while (buff = fgetc(in))
{
fprintf(stderr, "Character is: %d '%c' \n", buff, (char)buff);
if (buff == EOF)
{
break;
}
line[location] = (char)buff;
location++;
}
line[location] = '\0';
If you want to get a whole line, you can do this:
char line[MAX_LINE_SIZE];
fscanf(in, "%[^\n]", line);
//do whatever you need with the line
fscanf(in, "%[\n]", line);
The first fscanf call reads a whole line and store in variable line.
But it doesn't skip that line! If you use it again, it will store the very same line.
The second fscanf call is for this: it stores '\n' in variable line and skips the line you read previously.
If you want, you can create another buffer to get the '\n' and skip the line:
char garbage[2];
fscanf(in, "%[\n]", garbage);
I hope this helps.

read text file and store in array in c programming

I want read text file and store in array then show.
This is my code:
int i = 0, line = 5;
char ch[100];
FILE *myfile;
myfile = fopen("test.txt","r");
if (myfile== NULL)
{
printf("can not open file \n");
return 1;
}
while(line--){
fscanf(myfile,"%s",&ch[i]);
i++;
printf("\n%s", &ch[i]);
}
fclose(myfile);
return 0;
}
This is my text:
test 123562
856
59986
But result:
est
2356
56
9986
What is wrong? :(
ch[i] is holding a single character. Statement fscanf(myfile,"%s",&ch[i]); will scan string to ch[i] which can hold only one character. There is no place for '\0' which leads your program to undefined behavior.
Change
fscanf(myfile,"%s",&ch[i]);
to
fscanf(myfile,"%s",ch);
Previous answer was wrong. Behavior of program is well defined but you are scanning the file in a wrong manner. Your program will work as expected if you place i++; after printf statement.
while(line--){
fscanf(myfile,"%s",&ch[i]);
printf("\n%s", &ch[i]);
i++;
}
The reason is that &ch[i] is a pointer to the ith element of the array and string will be stored in array starting at position i. For the input given, this will work because the given array is large enough to hold the string.
You can do this as:
while(line--){
fscanf(myfile,"%s",ch);
printf("\n%s", ch);
i++;
}
but it will overwrite the array ch each time a string is scanned to it. Better to use a two dimensional array to store strings and read file with fgets.
You're not going to be able to fit five lines in the single char ch[100] array; that's just an array of 100 characters.
You can make it an array of arrays, i.e. char ln[5][100] which will give you room for five lines of 100 characters each.
Then you of course need to index into that array in the loop, i.e.:
for(int i = 0; i < 5; ++i)
{
if(fgets(ln[i], sizeof ln[i], myfile) == NULL)
{
fprintf(stderr, "Read error on line %d\n", i);
exit(1);
}
}
This uses fgets() which is much better suited at reading in whole lines; fscanf() will stop at whitespace with %s which is seldom what you want.
There is no need to use the ampersand in the scanf while getting the string. Make that into like this.
fscanf(myfile,"%s",&ch[i]);
to
fscanf(myfile,"%s",ch);
&ch[i] It will get the character for i th position in that array. If you want to get like that you can use the %c instead of %s. And change this one to.
printf("\n%s", ch);
While printing the string when you use the ampersand(&) that will access the address of that variable.
The program developed must be able to read the input files containing matrix A and matrix B
using fopen function
a. Matrix A and B of different size may be stored in different input file (if required).
Scan and assign matrix A and B as array using fscanf function and for loop
Perform matrix operations
a. Add matrix A and B
b. Subtract matrix A and B
c. Multiply matrix A and B
Use conditional statement if or switch for switching between 3, 4 and 5 elements matrix.
Print all input matrices and results obtained in a new file called output.dat using fprintf
function.
The output.dat file must have a header with the following information:
a. Student name
b. Student matric number
c. Class section
d. Lecturer name
e. Project title
Below the header, the output file must contain matrix A and B and the results from matrix
operation.
Use matrix A and B as given below:

Replace value in string with another from another string

I've been stuck for a while now. The program i'm writing basically changes the false words with the correct ones from the dictionary. However, when i run the program, it gives me no warnings or errors, but it doesn't display anything. Can you please help me?
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main(void){
char fname[20],word[2500], dictn[50];
int i,j;
float len1, len2;
FILE *inp, *dict, *outp, *fopen();
fpos_t pos1, pos2;
dict= fopen("dictionary.txt", "r");
printf("Enter the path of the file you want to check:\n");
scanf("%s", fname);
inp= fopen(fname, "r");
for(i=0;(fscanf(inp, "%s", word) != EOF); i++){
for(j=0;fscanf(dict, "%s", dictn) != EOF; j++){
fgetpos(inp, &pos1);
fgetpos(dictn, &pos2);
len1=(float)strlen(word);
len2=(float) strlen(dictn);
if(len1<=(0.6*len2)){
fsetpos(dictn, &pos1);
}
if(strncmp(word, dictn, 1)==0){
fsetpos(dictn, &pos1);
}
if(strcmp(word, dictn)==0){
fsetpos(dictn, &pos1);
}
}
printf("%s ", word);
}
fclose(inp);
fclose(dict);
return(0);
}
You can use
sprintf(word, "%s ", dictn);
If your code is working with printf it should work with sprintf, provided you don't overflow "word", including the NULL termination, so you might have to resize "word" if it is smaller than dictn.
First of all, I'm assuming you have created arrays word and dictn with enough size to hold the maximum length string any of your files.
First fault:
In loops you've created, i represents number of strings in input file and j represents number of strings in dictionary. word is your input string variable and dictn is your dictionary string variable. But you want to retrieve and alter word's ith or dictn's jth character. This may cause an error because there can be a case like this:
Suppose there are 10 words at inp file and 100 words at dictn. And in your loops, i have value of 8 and j have value of 88. Corresponding these i and j values, word has string value of, say, apple and dictn has string value of apple also. So this means apple is the 8th word at input file and 88th word at dictionary file. And if one of those if conditions was satisfied, compiler tries to apply a statement like word[i]=dictn[j];. This means word[8] = dictn[88]; for this example. But both of those string have apple as values which consists only 5 characters! And this will cause an error since you've tried to retrieve 88th character of a 5-length string and assign it to the 8th character of a 5-length string. So your code is wrong, it will only work for some cases which will be a rare situation.
Second fault:
I assume you want to read whole dictionary file for every word in input file but you will be able to read it for only first word of input file since you don't reopen it or set position indicator at the beginning of dictionary file after you read whole dictionary.
Third fault:
Your first if statement will never be reached assuming you have created len1 and len2 variables as integers. Because in your if statement, there is a multiplication of a decimal number and an integer which will return 0 as a result and since fscanf() ignores whitespaces, len1 and len2 will be at least 1.
Fourth fault:
Also your else if statement will never be reached because if a string has same value with another, their first character will also be equal to each other and your if statement where you compare their first characters will be also accepted.
Actually, I would write a code as solution but first of all you need to correct things up which are logically wrong because I do not know what you are really try to achieve by your code -just because I commented with full of assumptions-. But I can provide you some guidelines:
Convert your len1 and len2 variables from int to float and cast values which return from strlen() functions to float.
Reopen your dict file for every iteration of outside loop. (And do not forget not to close it).
To change your inp file, you can use a fpos_t type of variable to track your position indicator of your inp file (fgetpos() to get current position and fsetpos() to change position with value of fpos_t variable. You can search them.) and type the word with fprintf() or fputs() to that location to change that string.

Resources