How to find a string within a string in C? [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
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.
Closed 7 years ago.
Improve this question
First, I have already tried using the strstr() method that has been mentioned here, but this is not working for the problem I am trying to solve.
I am to obtain an input string from the user (the target string), which can be a word or a full sentence. It then scans an input text file line-by-line and checks if this input string exists in any lines of the file. If so, the corresponding text file line number and the full text file line in which the target string can be found is printed to the screen.
My problem while using the strstr(line, targetString) method is as follows:
Let's presume there is a sentence in the file, "I vigorously slapped that fish with a squirrel." Then, I enter my target string as, "I frolicked about the cat graveyard with unrelenting glee." It will show that the target string was matched, presumably because it is just finding a match with the "I". However, I need it to match only when it matches word-for-word of the target string to some substring within the text file line.
Any ideas how I might go about this? Thanks in advance!
Code:
FILE *inputFile = fopen(fileName, "r");
i = 1;
while (fgets(line, sizeof line, inputFile) != NULL)
{
if ((strlen(line) != 1) && (strstr(line, targetString)))
{
printf("Line %d: ", i);
printf("%s\n\n", line);
}
i++;
}

strstr() should work for your problem. Make sure both of the arguments actually have spaces and not \0 characters. strstr() like many standard C library functions treats \0 as a string terminator. Based on your description, I am going to guess the problem is that you read one line at a time and terminate each with a \0, then start matching one line at a time. You might be able to solve your problem if you read all of the strings at once into a buffer equal to the size of the file removing newline characters.
To be able to answer your question better, I would need to see your current source code with a test case that you expect to work.

My problem while using the strstr(line, targetString) method is as follows: Let's presume there is a sentence in the file, "I vigorously slapped that fish with a squirrel." Then, I enter my target string as, "I frolicked about the cat graveyard with unrelenting glee." It will show that the target string was matched, presumably because it is just finding a match with the "I".
This is not how strstr works. It doesn't match the first word/letter, it matches the entire string.

Let's presume there is a sentence in the file, "I vigorously slapped that fish with a squirrel." Then, I enter my target string as, "I frolicked about the cat graveyard with unrelenting glee." It will show that the target string was matched, presumably because it is just finding a match with the "I".
It sounds like you're interpreting the result of strstr() as an index into the string in question, but in fact the result is a char *, i.e. a pointer to the first match in the string. The 0 that you're getting back isn't the index the the first character, it's nil, meaning that there was no match.

Related

Using strcmp in a while condition to break the loop [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I need to write a program where the program needs to loop and get input from the user. In order to break the loop, the user will need to type exit on the keyboard.
The following is my code:
int main()
{
char input[100];
char terminate[100]="$exit";
//if input does not equals to terminate keep asking user for input
while(strcmp(input, terminate)!=0)
{
printf("$");
fgets(input,100,stdin);
}//otherwise, exit the program
}
I tried testing the code above but it keeps on looping even after typing the word exit. Your assistance is greatly appreciated. :)
fgets will read the EOL character which will be included in the final string.
You may use strncmp to just use the characters from "terminate": strncmp(input, terminate, strlen(terminate).
There are two (and possibly three) problems in your code as you show it:
The first, which is very serious, is that you use input before it's initialized. That means the contents of the array is indeterminate (and could be seen as "random" or "garbage"). That will very likely lead to undefined behavior when you use it in strcmp because it's not a proper null-terminated string.
The second problem is that fgets adds the ending newline in the buffer, so unless you remove it or add a newline in the string you compare with the strings will never be equal.
You can easily remove the newline from the input string by using the strcspn function:
input[strcspn(input, "\n")] = 0;
The possible third problem is that you seem to be adding the prompt $ in the string you compare. Unless the user actually writes the $ in the input given, it will not be part of the input.
You also don't need to use as many characters for the terminate array. Instead let the compiler decide the proper amount:
char terminate[] = "exit"; // The size of the array will be 5, including null-terminator
Figured it out. Here is my solution:
while(strncmp(input, terminate,4)!=0)
{
printf("$");
fgets(input,100,stdin);
}
use strncmp instead of strcmp.

fgets() and text files [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
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.
Closed 3 years ago.
Improve this question
My book mentions that fgets will read until it meets the (n-1)th character or a character of a new line. By character of new line do we only mean Enter (\n)? I am asking this because what I did was to create a text file on which I started typing in some nonsense, surpassing the character limit of each line meaning that I used more than one lines. After that I used fgets and what I expected was it to read only the characters in the first line of the text file but what it did was read all of them.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char box[5000];
FILE *fp;
fp = fopen("test.txt", "r");
fgets(box, 5000, fp);
puts(box);
}
Test.txt (The text is random that's why it's silly) (285 characters):
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk25kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkggggggggggiiiiiiiiiiiiiiiiiiii
So the result I expected was for it to print only part of the text and actually as many characters as the limit that is set for one line, minus one, (which I think is something above 250). But instead of that, it prints all of them. Note: The same thing happens even I type even more characters in the file.
You seem to be assuming that there's an upper limit, perhaps 255 characters, on the length of a line in a text file. C imposes no such limit, except indirectly by using int as the size argument to fgets.
Your program defines a 5000-character array and calls fgets with a length argument of 5000. That means it can read a single line of up to 5000 characters (or close to that; I'm ignoring a couple of off-by-one issues for the '\n' and '\0' characters). The input line in your question is only 285 characters long, so your program will easily read it as a single line.
You can try changing the length of your array to see what happens when an input line is too long to fit:
char box[255];
...
fgets(box, sizeof box, fp);
Note that using sizeof box rather than repeating the number means the call won't get out of sync with the array size.
It only stops at the newline character \n or at n-1 characters. There is no newline character other than \n.
As you set the limit for your buffer and the amount fgets can read to 5000, it can easily read all the characters in your file and print them.
There is no line length limit in ISO C (ISO/IEC 9899), whether one is imposed by your book or not. Your book is probably outdated.

Program to find Word Length Statistics [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I am expected to make a program to calculate and display statistics about the length of words in a text file. I have been provided the following file
int readFile(const char fName[], char textStr[]){
FILE *fPtr;
char ch;
int size = 0;
if ((fPtr = fopen(fName, "r")) == NULL) {
fprintf(stderr, "Error, failed to open %s: ", fName);
perror("");
return 1;
}
while ((ch = fgetc(fPtr)) != EOF) {
if (size >= MAX_FILE - 1)
break;
textStr[size++] = ch;
}
textStr[size] = '\0';
return size;
}
I was able to verify that I can access the file using the following code
int main() {
char str[MAX_FILE];
int len = readFile("test.txt", str);
if (len == -1) {
printf("An error occurred\n");
} else {
printf("file read");
}
}
File test.txt contains
The quick brown fox jumps over the lazy dog
What I want to do is to get the contents of test.txt and find the length of each word in it something like:-
1 letter words- 0
2 letter words - 0
3 letter words - 3
4 letter words -4
and so on...
As a fellow new contributor, I'm going to give you a break and try to answer the question you didn't ask. ;)
I believe the question is "how to proceed". This is going to be a long answer as I will try be very detailed since you seem to be a newbie. Hopefully this will help you or maybe someone else.
The trick is to take a word problem and convert it into a mathematical solution. The best way to do this is to write "pseudocode". (See Wikipedia for more information, if you need to.) I'm going to give you some pseudocode at the end, but since this appears to be a homework assignment, please try to write your own pseudocode first. If you read the pseudocode and it still doesn't help, I can post my solution later. (I'm not a great programmer so it might not be the best program. And it took way overlong to come up with it.)
First things first: There appears to be a typo in the code you posted. In the source code you were provided, the problem is the return 1 statement if the file isn't found. That should be return -1, because what would happen if you had a test file that had exactly 1 letter? The code wouldn't work correctly.
Now, to first convert the word problem you were given: You need to have an array of word counts to keep track of 1-letter, 2-letter, etc. words. Now according to this the longest word in the English dictionary is 45 letters. So, in theory, you would need to have an array of 45 elements of wordCounts. You can shorten this as required.
Now to process your str variable, you need a while statement to go through one character at a time. Since the characters in the string go from element 0 through one less that the len variable, you need to code the while accordingly.
Within that while, you need another while. This while needs to count up the wordLength one character at a time, until you see a blank or the trailing '/0' character of str. To do this, you initialize the wordLength to zero right before the second while. Then add 1 to the wordLength for each character you count and increment your subscript.
At the end of this inner while you need to accumulate your wordCounts. Keep in mind that your 1-letter words are going to be accumulated into element 0 of your array. So you need to adjust the wordLength - 1 array element. After that you need to increment your subscript you are using to go through your str, one character at a time.
At the end, you need to print out the wordCounts array values. Since most of the word lengths will have a value of zero, I wouldn't print these. Unless you set the maximum length of the wordCounts array to something like 10, instead of 45. You want a for loop to go through your wordCounts array, and do something like this: printf("%2d letter words = %d", ..., ...);. Keep in mind your 1-letter words are going to be in element 0;
That is a very detailed version of a word problem that is the solution to the problem of "count the number of words that the phrase has from 1-letter words to x-letter words".
Here is the pseudocode I came up with, after coding my solution. It is a little more detailed than normal pseudocode would be. (Personally, I abbreviate all variable names and use Pascal case, but that's just me.)
Declare a numeric array of wordCounts and a subscript.
For each element of wordCounts, zero out the number of words or the code won't work right.
Reinitialize subscript to zero.
As long as (while) the subscript is less than the len, continue.
Initialize the wordLength to zero.
As long as the str[subscript] is not a blank or a null character, add 1 to the wordLength.
Increment the subscript.
After both while statements are complete print out the array of wordLengths, as described above.
Your done!
Now I could post the actual code that could be used to come up with this pseudocode, but it would be better if you came up with it yourself. If you try but have a bug in your code, post a new question, and I'll try to check back to answer it. Hope this helps you or someone else.

Unusual character when writing to file [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
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.
Closed 6 years ago.
Improve this question
I've created a struct with 2 char[] and one int. I created an array of this struct and scanfed several inputs to store data into the array. Then I used fprintf to write this data to the file. But when I open the file I get û before every new record. Idk why is it happening.
Here's the relevant code:
FILE *outputFile=fopen("1021.txt","ab");
int tickets=0,i=1;
struct air s[30];
printf("\nEnter Number of tickets:");
scanf("%d",&tickets);
for (i=1;i<=tickets;i++)
{
printf("\nEnter the name\t");
scanf("%s",&s[i].name);
printf("\nEnter the phone number\t");
scanf("%s",&s[i].phoneNo);
printf("\n Enter the address\t");
scanf("%s",&s[i].address);
printf("Your ticket is confirmed\t");
getch();
}
for (i=0;i<=tickets;i++)
{
printf("%s", s[i].name);
printf("%s", s[i].phoneNo);
printf("%s", s[i].address);
fprintf(outputFile,"%s",s[i].name);
fprintf(outputFile,"%s",s[i].phoneNo);
fprintf(outputFile,"%s",s[i].address);
}
Here's what I get in the file:
ûdalla03332228458dallaÈfsÇûÿÿÿÿàrancho03312041265dallabancho
Where are those unusual characters coming from?
Your input loop is
for (i=1;i<=tickets;i++)
but the output loop is
for (i=0;i<=tickets;i++)
So you are writing data to file from element [0] that you have no data entered for. That is why it is junk.
In C, arrays are indexed from [0], and neither of those loops is right. Please change both of them to
for (i = 0; i < tickets; i++)
There are other problems in the code too, but this addresses the immediate "uninitialised data" problem.
Edit: some other problems.
You opened the file in "binary" mode, but you are using it as a text file. I believe the distinction is only necessary in Windows.
FILE *outputFile=fopen("1021.txt", "at"); // change to "t"
The string address passed to scanf should not contain an & address-of (unlike an int). Just pass the array - it decays to the required pointer.
scanf("%s", s[i].name); // removed `&`
As you have not written any newline to file to demark your string data, when you read the data back in, you will not know where each ends and the next begins. So for example, add the newline like this
fprintf(outputFile, "%s\n", s[i].name); // added \n
You say one member is an int presumably the phone number, but you are inputting as a string. Yet it is a bad idea to store phone numbers as integers, because a) thay might contain a character such as '+' or b) may start with a leading 0 and that will be lost when you store as int. So change the struct member phoneNo to be a char array of adequate length.
The scanf format specifier %s will stop at the first whitespace it meets, so the input statements will be better as this, which will only stop when it finds a newline or hits the length limit:
int res = scanf("%29[^\n]", s[i].name);
where the array length defined was [30] (you did not show the struct). Alternatively you could research the use of fgets().
Finally, you should check the return value of the functions you are calling to see if they were successful. fopen will tell you if the file opened correctly. scanf will tell you the number of entries it scanned, and fgets tells you if it was successful too.

Reading and comparing numbers from txt file C

I am new to C programming, so I am having difficulties with the problem below.
I have a text file inp.txt which contains information like the following:
400;499;FIRST;
500;599;SECOND;
670;679;THIRD;
I need to type a number and my program needs to compare it with numbers from the inp.txt file.
For example, if I type 450, it's between 400 and 499, so I need write to the word FIRST to the file out.txt
I have no idea how to convert a character array to an int.
I think you'll want these general steps in your program (but I'll leave it to you to figure out how you want to do it exactly)
Load each of the ranges and the text "FIRST", "SECOND", etc. from the file inp.txt, into an array, or several arrays, or similar. As I said in the comment above, fscanf might be handy. This page describes how to use it - the page is about C++, but using it in C should be the same http://www.cplusplus.com/reference/clibrary/cstdio/fscanf/. Roughly speaking, the idea is that you give fscanf a format specifier for what you want to extract from a line in a file, and it puts the bits it finds into the variables you specify)
Prompt the user to enter a number.
Look through the array(s) to work out which range the number fits into, and therefore which text to output
Edit: I'll put some more detail in, as asker requested. This is still a kind of skeleton to give you some ideas.
Use the fopen function, something like this (declare a pointer FILE* input_file):
input_file = fopen("c:\\test\\inp.txt", "r") /* "r" opens inp.txt for reading */
Then, it's good to check that the file was successfully opened, by checking if input_file == NULL.
Then use fscanf to read details from one line of the file. Loop through the lines of the file until you've read the whole thing. You give fscanf pointers to the variables you want it to put the information from each line of the file into. (It's a bit like a printf formatting specifier in reverse).
So, you could declare int range_start, range_end, and char range_name[20]. (To make things simple, let's assume that all the words are at most 20 characters long. This might not be a good plan in the long-run though).
while (!feof(input_file)) { /* check for end-of-file */
if(fscanf(input_file, "%d;%d;%s", &range_start, &range_end, range_name) != 3) {
break; /* Something weird happened on this line, so let's give up */
else {
printf("I got the following numbers: %d, %d, %s\n", range_start, range_end, range_name);
}
}
Hopefully that gives you a few ideas. I've tried running this code and it did seem to work. However, worth saying that fscanf has some drawbacks (see e.g. http://mrx.net/c/readfunctions.html), so another approach is to use fgets to get each line (the advantage of fgets is that you get to specify a maximum number of characters to read, so there's no danger of overrunning a string buffer length) and then sscanf to read from the string into your integer variables. I haven't tried this way though.

Resources