I'm trying to do this exercise for my exam tomorrow.
I need to compare a string of my own input and see if that string is appearing on the file. This needs to be done directly on the file, so I cannot extract the string to my program and compare them "indirectly".
I found this way but I'm not getting it right, and I don't know why. The algorithm sounds good to me.
Any help, please? I really need to focus on this one.
Thanks in advance, guys.
#include<stdio.h>
void comp();
int main(void)
{
comp();
return 0;
}
void comp()
{
FILE *file = fopen("e1.txt", "r+");
if(!file)
{
printf("Not possible to open the file");
return;
}
char src[50], ch;
short i, len;
fprintf(stdout, "What are you looking for? \nwrite: ");
fgets(src, 200, stdin);
len = strlen(src);
while((ch = fgetc(file)) != EOF)
{
i = 0;
while(ch == src[i])
{
if(i <= len)
{
printf("%c - %c", ch, src[i]);
fseek(file, 0, SEEK_CUR + 1);
i++;
}
else break;
}
}
}
Your logic after matching the first character looks suspect. There's no need to seek in the file, you need to read more content to try to match the later bytes from src and resetting i on each iteration prevents you from checking later characters from src.
The following (untested) code should be closer to the mark
i = 0;
while((ch = fgetc(file)) != EOF) {
if (ch != src[i]) {
i = 0;
}
else if (++i >= len) {
printf("found %s in file\n", src);
break;
}
}
It relies on repeated calls to fgetc rather than fseek and only resets the index into src when a character doesn't match.
Note also that
char src[50];
fgets(src, 200, stdin);
is slightly wrong. It tells fgets that it can write up to 200 chars to src. Writing any more than 50 will write beyond the memory allocated for src, with undefined consequences. You should change this to
char src[50];
fgets(src, sizeof(src), stdin);
while((ch = fgetc(file)) != EOF)
{
if(ch != compare[i]){
i = 0;
}
else{
i++;
}
if(i >= strlen(compare){
printf("we have a match");
break;
}
}
Related
I am new at c and I am writing a code that get a string from the user and compare it to a strings from the text file and my code is only working when I compare between two characters and when I compare between two strings it's not working If someone know how can I fix the problem it's will be verey helpful. the compare line is in the searchFile function. the text file is a csv file so insted compare the char to string I need to compare between what befor the , to the string_to_search. example for csv file at the end of the code
Example: string to search = 'c' work, string to search 'name' doesn't work
#include <stdio.h>
#define STR_LEN 100
int searchFile(char* string_to_search, char* path);
int main(int argc, char* argv[])
{
FILE* text_file = 0;
int found = 0, choice = 0;
char string_to_search[STR_LEN] = {0};
if (!(fopen(argv[1], "r") == NULL)) //check if file exists
{
do
{
printf("Please enter your choice:\n");
printf("1 - Search a term in the document.\n");
printf("2 - change a value in a specific place.\n");
printf("3 - copy a value from one place to another\n");
printf("4 - Exit\n");
scanf("%d", &choice);
getchar();
switch (choice)
{
case 1:
fgets(string_to_search, STR_LEN, stdin);
string_to_search[strcspn(string_to_search, "\n")] = 0;
found = searchFile(string_to_search, argv[1]); //found = where the string line
if (found != 0)
printf("Value was found in row %d\n", found);
else
printf("Value Wasn't Found\n");
}
}while(choice != 4);
}
else
{
printf("file does not exists\n");
}
getchar();
return 0;
}
int searchFile(char* string_to_search, char* path)
{
FILE* file = fopen(path, "r");
char ch = ' ';
int i = 0, len = 0, count = 1;
fseek(file, 0, SEEK_END);
len = ftell(file);
fseek(file, 0, SEEK_SET);
len = len - 2;
char* string = (char*)malloc(sizeof(char) * len);
do //copying the chars to a string
{
ch = fgetc(file);
string[i] = ch;
i++;
} while (ch != EOF);
fclose(file);
for (i = 0; i < len; i++)
{
if (string[i] == *string_to_search) //the compare
{
free(string);
return count;
}
if (string[i] == '\n')
{
count++;
}
}
free(string);
return 0;
}
Example for a CSV file:
roee,itay,3,4
5,6,7,8
a,b,c,d
e,f,g,h
You have to change the following line:
if (string[i] == *string_to_search) //the compare
into
if (string[i] == string_to_search[i]) //the compare
The problem is that *string_to_search always refers to the first character of string_to_search. With the [i] you will get the nth character of the string as you have done it for the variable string. So as you noticed it works for a comparsion of two characters but not for two strings, because on a string you will always compare with the first character of string_to_search. For example if you want to compare "aaa" it will also work.
But as noted in the comment section you may also want to use strcmp() instead of the loop. There you will also have to pass string_to_search and not *string_to_search, because you want to pass the pointer to the string and not a single character.
Here's my issue I'm running into.
I'm reading in lines of text from a file, but only trying to read in lines that aren't consecutive repeats.
Here's my regular code for reading in the lines of text.
while (((ch = getc (fp)) != EOF))
{
a[j++] = ch;
}
a[j] = '\0';
which works just fine.
When trying to figure out how to go about the problem, I tried having a char array that would read in a line at a time, and then compare it to the previous line using strcomp. If it was a match, it would not add that line into the final char array. It looks something like this:
while (((ch = getc (fp)) != EOF))
{
if (ch != '\n')
{
copynumber++;
temp[j] = ch;
}
else
{
uni = strcmp(identical, final);
if (uni == 0) {
copynumber = 0;
}
else
{
strncpy(identical, temp, copynumber);
final[j] = ch;
}
j++;
}
}
final[j] = '\0';
but I know this won't work for a few reasons. One, I never add the previous chars into the final array. I'm really just lost. Any help is appreciated. Thank you.
There is a getline() function in stdio.h that you can use to get each line in a file.
To skip duplicates you can store the previous line read and compare at each step.
FILE *fp;
char *line = NULL;
char *prev_line[999];
char final[999];
size_t len = 0;
ssize_t read;
fp = fopen("file", "r");
while ((read = getline(&line, &len, fp)) != -1) { // Read each line
if (strncmp(line, prev_line, read) != 0) { // If not equal
strncat(final, line, read); // Copy to final
strncpy(prev_line, line, read); // Update previous
}
}
free(line); // Need to free line since it was null when passed to getline()
I am learning file handling in C. I wrote code to replace a line in a file with a string input by the user. The replacing progress itself works great, but somehow the first line is always empty and I am able to understand what goes wrong.
Additionally I have some additional questions about file handling itself and about tracking down the mistakes in my code. I understand by now that I should have used perror() and errno. This will be the next thing I will read on.
Why shouldn't I use "w+" establishing the file stream? (A user on here told me to better not use it, unfortunately I couldn't get an explanation)
I tried to use gdb to find the mistake, but when I display my fileStored array I get only numbers, since its obviously an int array, how could I improve the displaying of the variable
What would be a good approach in gdb to track the mistake down I made in the code?
The code:
#include <stdio.h>
#include <stdlib.h>
#define MAXLENGTH 100
int main(int argc, char *argv[]){
FILE *fileRead;
char fileName[MAXLENGTH],newLine[MAXLENGTH];
int fileStored[MAXLENGTH][MAXLENGTH];
short lineNumber, lines = 0;
int readChar;
printf("Input the filename to be opened:");
int i = 0;
while((fileName[i] = getchar()) != '\n' && fileName[i] != EOF && i < MAXLENGTH){
i++;
}
fileName[i] = '\0';
if((fileRead = fopen(fileName, "r")) == NULL){
printf("Error: File not found!\n");
return EXIT_FAILURE;
}
i = 0;
while((readChar = fgetc(fileRead)) != EOF){
if(readChar == '\n'){
fileStored[lines][i] = readChar;
i = 0;
lines++;
}
fileStored[lines][i] = readChar;
i++;
}
fclose(fileRead);
fileRead = fopen(fileName, "w");
printf("Input the content of the new line:");
i = 0;
while((newLine[i] = getchar()) != '\n' && newLine[i] != EOF && i < MAXLENGTH){
i++;
}
newLine[i] = '\0';
printf("There are %d lines.\nInput the line number you want to replace:",lines);
scanf("%d",&lineNumber);
if((lineNumber > lines) || (lineNumber <=0)){
printf("Error: Line does not exist!");
return EXIT_FAILURE;
}
int j = 0;
for(i = 0; i < lines; i++){
if(i == lineNumber-1){
fprintf(fileRead,"\n%s",newLine);
continue;
}
do{
fputc(fileStored[i][j],fileRead);
j++;
}while(fileStored[i][j] != '\n');
j = 0;
}
fclose(fileRead);
return EXIT_SUCCESS;
}
I am very new to C. I am trying to read the words from a file which contains lots of not alpha characters. My input file looks something like this %tOm12%64ToMmy%^$$6 and I want to read tom first and then put tom in my data structure and then read tommy and put that in my data structure all in lowercase. This is what I have tried until now. All my other code works as I have manually sent the parameters to the methods and there are no errors. This is what I have tried to read the words from the file. A word can be of 100 characters max. Can someone help me understand the logic and possibly this code.I am very lost.Thank You!
void read(FILE *fp)
{
FILE *fp1 = fp;
char word[100];
int x;
int counter = 0;
while ((x = fgetc(fp1)) != EOF)
{
if (isalpha(x) == 0)
{
insert(&tree,word);
counter = 0;
}
if (isalpha(x) != 0)
{
tolower(x);
word[counter] = x;
counter++;
}
}
rewind(fp1);
fclose(fp1);
}
char *getWord(FILE *fp){
char word[100];
int ch, i=0;
while(EOF!=(ch=fgetc(fp)) && !isalpha(ch))
;//skip
if(ch == EOF)
return NULL;
do{
word[i++] = tolower(ch);
}while(EOF!=(ch=fgetc(fp)) && isalpha(ch));
word[i]='\0';
return strdup(word);
}
void read(FILE *fp){
char *word;
while(word=getWord(fp)){
insert(&tree, word);
}
//rewind(fp1);
fclose(fp);
}
This is a simplification of #BLUEPIXY 's answer. It also checks the array boundaries for word[]
char *getword(FILE *fp)
{
char word[100];
int ch;
size_t idx ;
for (idx=0; idx < sizeof word -1; ) {
ch = fgetc(fp);
if (ch == EOF) break;
if (!isalpha(ch)) {
if (!idx) continue; // Nothing read yet; skip this character
else break; // we are beyond the current word
}
word[idx++] = tolower(ch);
}
if (!idx) return NULL; // No characters were successfully read
word[idx] = '\0';
return strdup(word);
}
So what I'm trying to do is to count blank lines, which means not only just containing '\n'but space and tab symbols as well. Any help is appreciated! :)
char line[300];
int emptyline = 0;
FILE *fp;
fp = fopen("test.txt", "r");
if(fp == NULL)
{
perror("Error while opening the file. \n");
system("pause");
}
else
{
while (fgets(line, sizeof line, fp))
{
int i = 0;
if (line[i] != '\n' && line[i] != '\t' && line[i] != ' ')
{
i++;
}
emptyline++;
}
printf("\n The number of empty lines is: %d\n", emptyline);
}
fclose(fp);
You should try and get your code right when posting on SO. You are incrementing both i and emptyline but the use el in your call to printf(). And then I don't know what that is supposed to be in your code where it has }ine. Please, at least make an effort.
For starters, you are incrementing emptyline for every line because it is outside of your if statement.
Second, you need to test the entire line to see if it contains any character that is not a whitespace character. Only if that is true should you increment emptyline.
int IsEmptyLine(char *line)
{
while (*line)
{
if (!isspace(*line++))
return 0;
}
return 1;
}
Before getting into the line loop increment the emptyLine counter and if an non whitespace character is encountred decrement the emptyLine counter then break the loop.
#include <stdio.h>
#include <string.h>
int getEmptyLines(const char *fileName)
{
char line[300];
int emptyLine = 0;
FILE *fp = fopen("text.txt", "r");
if (fp == NULL) {
printf("Error: Could not open specified file!\n");
return -1;
}
else {
while(fgets(line, 300, fp)) {
int i = 0;
int len = strlen(line);
emptyLine++;
for (i = 0; i < len; i++) {
if (line[i] != '\n' && line[i] != '\t' && line[i] != ' ') {
emptyLine--;
break;
}
}
}
return emptyLine;
}
}
int main(void)
{
const char fileName[] = "text.txt";
int emptyLines = getEmptyLines(fileName);
if (emptyLines >= 0) {
printf("The number of empty lines is %d", emptyLines);
}
return 0;
}
You are incrementing emptyline on every iteration, so you should wrap it in an else block.
Let's think of this problem logically, and let's use functions to make it clear what is going on.
First, we want to detect lines that only consist of whitespace. So let's create a function to do that.
bool StringIsOnlyWhitespace(const char * line) {
int i;
for (i=0; line[i] != '\0'; ++i)
if (!isspace(line[i]))
return false;
return true;
}
Now that we have a test function, let's build a loop around it.
while (fgets(line, sizeof line, fp)) {
if (StringIsOnlyWhitespace(line))
emptyline++;
}
printf("\n The number of empty lines is: %d\n", emptyline);
Note that fgets() will not return a full line (just part of it) on lines that have at least sizeof(line) characters.