Comparing char to string - C - c

so I've viewed multiple threads here now on this site about comparing my char array to a string or something of that sort with things like strcmp and strstr however whenever I compiled it, I got the error:
warning: incompatible implicit declaration of built-in function 'strstr' [enabled by default]
and honestly I have no idea what this means. I'm relatively new to C...
So here's my code:
int main(){
FILE * fPointer;
fPointer = fopen("test.txt", "r");
char action[10];
char num[100];
char* s;
while(fscanf(fPointer, "%s", action) != EOF){
s = strstr(action, "JUMP");
if(s != NULL){
puts("Jump");
}else{
puts("Don't Jump");
}
}
fclose(fPointer);
}
I've tried a few other things, but none of them worked out. My text file has a bunch of actions:
JUMP 4
CRUNCH 7
SITUP 8
and other similar things like that. I wanted the while loop to scan for each action, and then compare it to whatever to see if action is = to "jump" etc, etc, and if it is, then scan the number to tell me how many times to do each action.
Can someone help me with this? Thanks so much!

You haven't included the proper header.
#include <string.h>

Related

Need help using the strsep function in c

int main(int argc, char *argv[])
{
char *line, buffer[1024];
char *token, *setValue, *pointer;
FILE *fp = fopen("file", "r");
if(fp == NULL)
{
printf("File was unable to be opened.\n");
}
fgets(buffer,1024,fp);
printf("%s\n", buffer);
while(fgets(buffer,1024,fp) != NULL)
{
strcpy(token, strsep(&buffer, ","));
printf("%s\n", token);
}
return 0;
}
I'm having a bit of trouble understanding how strsep works.. I've looked up tutorials for it, but when I try different methods, it keeps just not being able to compile.. It'd be appreciated if someone helped me understand the syntax and the way it works. Thank you.
**EDIT: 'Buffer' contains "I,was,in,the,school"
****EDIT x2: I'm trying to parse a csv file, and using the basic 'Buffer' I created on my desktop as an example. I want to separate the different words by the respective comma.
regarding:
strcpy(token, strsep(&buffer, ","));
the variable token is ONLY a pointer, it has not been set to point to any memory that the application owns. Therefore, it will contain what ever trash was on the stack at the location of the variable.
The result is undefined behavior and it can lead to a seg fault event.
Suggest declare token as
char token[ 1024 ];
so it is large enough to hold a maximum length string (I.E. the length of buffer[]
as it the above wasn't bad enough:
the posted code is missing the statement: #include <string.h> so as to expose the prototype for the function strsep() so the compiler will make the assumption that the parameters and returned value are int rather than their actual types.
The posted code is also missing the statement: #include <stdio.h> so the parameter and return types for the functions: fopen(), fgets(), printf()and even the struct type forFILEare assumed to beint` rather than their actual types.

variadic function- reading files (c)

i need to create a variadic function (stdarg library) which will loop through all the files i pass it and will count words similiar to a word i pass as a parameter,
#include <stdio.h>
#include <stdarg.h>
void countWords(char* name, FILE* file, ...){
va_list params;
FILE* currentFile;
FILE* f;
int words = 0;
va_start(params, file);
currentFile = file;
while (currentFile != NULL)
{
f = fopen(currentFile, "r+"); //which file should i open every time? this doesnt compile
// comparing words in each file code
currentFile = va_arg(params, FILE*);
}
va_end(params);
}
i cant read the file (no metter what i try it doesnt compile),
and how can i loop through each file comparing my word? i would really appreciate guidance
thank you!
If you are passing the file name or more precisely the path to the file, then this
FILE *currentFile;
currentFile = va_arg(params, FILE *);
should be
char *currentFile;
currentFile = va_arg(params, char *);
If you pass FILE pointers, you should not open them because if the rest of the program is correct then they shall be already opened inside the funcion, otherwise it doesn't make any sense to pass FILE *'s.
So the function should probably be
#include <stdio.h>
#include <stdarg.h>
void countWords(char *word, char *filename, ...)
{
va_list params;
FILE *file;
int words;
words = 0;
va_start(params, file);
while (filename != NULL)
{
file = fopen(filename, "r+");
// comparing words in each file code
filename = va_arg(params, char *);
}
va_end(params);
}
You would call it like this
countWords("example", "/path/to/file/1", ..., "/path/to/file/n", NULL);
and you should be careful with string literals probably use the const qualifier in this situation, because even if the parameters are not string literals it wouldn't make sense to modify them inside countWords() so to prevent accidentally modifying them const could help, although you can always modify them anyway. Even if modifying a string literal invokes undefined behavior you cannot completely forbid your program from doing so.
i need to create a variadic function
Unless this is a homework assignment about variadic functions, you don't need a variadic function at all. Variadic functions are not type safe and type safety is a desirable property.
Others have already pointed this out: You need a function that takes a filename and counts the occurrences of a word in a single file
size_t occurrences(const char *word, const char *filename) { ... }
You can then easily loop over an array of files, e.g.:
size_t count = 0;
for (int i = 1, i < argc; i++) {
size += occurrence("pink", argv[i]);
}
If you like, you can wrap this in a separate function which takes an array of file names with a file count. This is easily done, because whether you take your files from a command line or from somewhere else, you already have them stored in some kind of array.
Now consider the variadic variant, which makes sense only if you know the files you want to process at compile time, e.g.:
size_t n = var_occurrences("banana",
"alpha.txt", "beta.txt", "gamma.txt", NULL);
The same can be achieved with the non-variadic approach:
const char *w = "banana";
size_t n = occurrences(w, "alpha.txt")
+ occurrences(w, "beta.txt")
+ occurrences(w, "gamma.txt");
This is a bit more typing, but everything else is much more straightforward. If you must use variadic functions, go ahead and look at iharob's answer. But variadic functions are not a good solution to your task.

Reading in char from file into struct

For my assignment, I have to read in a text file with a varying amount of lines. They follow the following format:
AACTGGTGCAGATACTGTTGA
3
AACTGGTGCAGATACTGCAGA
CAGTTTAGAG
CATCATCATCATCATCATCAT
The first line is the original line I will testing the following ones against, with the second line giving the number of remaining lines.
I'm having trouble trying to save these to a struct, and can't even get the first line to save. I tried using the void function with an array and it seems to work, but can't seem to transfer it over to structs.
Here's my code so far:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define LENGTH 25
struct dna {
char code[LENGTH];
};
int main(){
char filename[] = "input1.txt";
FILE *input = fopen("input1.txt","r");
char firstDna[LENGTH]="";
struct dna first;
struct dna first.code[]= "";
makeArray(input,first);
// printf("%s",filename);
system("pause");
return 0;
}
void makeArray(FILE *input,struct dna first){
int i=-1;
//nested for loops to initialze array
//from file
while(i != '\n'){
fscanf(input,"%c",first[i].code);
printf("%c", first[i].code);
i++;
}//closing file
fclose(input);
}
Since this is for a class assignment, I want to preface this by saying that a good way to tackle these types of assignments is to break it up into tasks, then implement them one by one and finally connect them. In this case the tasks might be something like:
parse the first line into a (struct containing a) char array.
parse the number into an int variable
parse each remaining line in the file like you did with the first line
test the first line against the other lines in the file (except the number)
You also mentioned in a comment that the struct is for extra credit. For that reason, I'd recommend implementing it using just a char array first, then refactoring it into a struct once you have the basic version working. That way you have something to fall back on just in case. This way of developing might seem unnecessary at this point, but for larger more complicated projects it becomes a lot more important, so it's a really good habit to get into as early as possible.
Now, let's look at the code. I'm not going to give you the program here, but I'm going to identify the issues I see in it.
Let's start with the main method:
char filename[] = "input1.txt";
FILE *input = fopen("input1.txt","r");
This opens the file you're reading from. You're opening it correctly, but the first line is in this case unnecessary, since you never actually use the filename variable anywhere.
You also correctly close the file at the end of the makeArray function with the line:
fclose(input);
Which works. It would, however, probably be better style if you put this in the main method after calling the makeArray function. It's always a good idea to open and close files in the same function if possible, since this means you will always know you didn't forget to close the file without having to look through your entire program. Again, not really an issue in a small project, but a good habit to get into. Another solution would be to put the fopen and fclose functions in the makeArray function, so main doesn't have to know about them, then just send the char array containing the filepath to makeArray instead of the FILE*.
The next issue I see is with how you are passing the parameters to the makeArray function. To start off, instead of having a separate function, try putting everything in the main method. Using functions is good practice, but do this just to get something working.
Once that's done, something you need to be aware of is that if you're passing or returning arrays or pointers to/from functions, you will need to look up the malloc and free functions, which you may not have covered yet. This can be one of the more complex parts of C, so you might want to save this for last.
Some other things. I won't go into detail about these but try to get the concepts and not just copy paste:
struct dna first.code[]= ""; should probably be first.code[0] = \0;. \0 is used in C to terminate strings, so this will make the string empty.
Passing %c to fscanf reads a single character (you can also use fgetc for this). In this case, it will probably be easier using %s, which will return a word as a string.
Assuming you do use %s, which you probably should, you will need to call it twice before the loop - once to get the first DNA sequence and another time to get the number of other DNA sequences (the number of iterations).
Each iteration of the loop will then test the original DNA sequence against the next DNA sequence in the file.
I hope that helps!
sample to fix
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define LENGTH 25
struct dna {
char code[LENGTH];
};
struct dna *makeArray(FILE *input, int *n);//n : output, number of elements
int main(void){
char filename[] = "input1.txt";
FILE *input = fopen(filename,"r");
struct dna first = { "" };
fscanf(input, "%24s", first.code);//read first line
printf("1st : %s\n", first.code);
int i, size;
struct dna *data = makeArray(input, &size);//this does close file
for(i = 0; i < size; ++i){
printf("%3d : %s\n", i+1, data[i].code);
}
free(data);//release data
system("pause");
return 0;
}
struct dna *makeArray(FILE *input, int *n){//n : output, number of elements
int i;
fscanf(input, "%d", n);//read "number of remaining lines"
struct dna *arr = calloc(*n, sizeof(struct dna));//like as struct dna arr[n] = {{0}};
for(i = 0; i < *n; ++i){
fscanf(input, "%24s", arr[i].code);
}
fclose(input);
return arr;
}
a simple fix might be :
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define LENGTH 25
struct dna {
char code[LENGTH];
};
void makeArray(FILE *input,struct dna *first){
int i=0;
fscanf(input,"%c",&first->code[i]);
printf("%c",first->code[i]);
while(first->code[i] != '\n' && i < LENGTH){
i++;
fscanf(input,"%c",&first->code[i]);
printf("%c",first->code[i]);
}
}
int main() {
struct dna first;
char filename[] = "input1.txt";
FILE *input = fopen(filename,"r");
makeArray(input,&first);
fclose(input);
printf("%s",first.code);
return 0;
}
PS: i tried to not change your original code
in order to change the code[Length] in the makeArray function you will have to pass it's adresse this is why i call mkaeArray function this way : makeArray(input,&first);.

Using strcmp to compare a char pointer and a literal

I've been trying this for about an hour and looked at other places online but still was not able to accomplish what I'm trying to do. This should probably be something simple but I have not coded in C in quite awhile so I may be missing something. Anyway I want to use strcmp to compare something in a variable called char *args and a literal like "qw".
I am in main and pass a function this args variable and when I get it back I want to compare like this: Maybe I am just completely doing this in a dumb way.
char *args;
char **svdArray;
int keepTrack = 0;
int beforeTrack = 0;
svdArray = malloc(5*sizeof(char*));
while (1)
{
if(!(strcmp(args[0], "r")) && (!strcmp(args[0], "rr")))
{
svdArray[keepTrack] = args[0];
keepTrack++;
}
All I want to happen is if I args[0] has something in it besides rr or r I want to execute the code inside the if statement. However as of now the flow just never enters it and I don't know why.
Any help would greatly be appreciated!!!
strcmp() compares both strings in whole.
To only test for parts use strstr() like for example so:
if (strstr(args, "r")) || strstr(args, "rr")))
{
svdArray[keepTrack] = args;
keepTrack++;
}
You need to pass a char* to strcmp, like args.
Here is the prototype for strcmp from here:
int strcmp ( const char * str1, const char * str2 );
So since args is a char* and "r" will give you a char* you should try:
/* since you're learning, print out what this thing does */
#include <stdio.h>
printf("Output: %d\n",strcmp(args,"r"));

Writing to a file in a C (Linux). What's wrong?

2 days ago I've installed linux on my machine (1st time in my life :P) and now I'm tryin to write a char into a file. For some reason, it's not working... Here's my code.
#include <stdio.h>
#include <fcntl.h>
int main (int xd, char *tab[]) {
char *path1 = tab[1];
int filee = open(path1, O_WRONLY | O_CREAT| O_TRUNC, 0777);
write(filee, 'x', sizeof(char));
close(filee);
return 0;
}
What could be wrong in this little piece of code? I've checked and function 'write' returns -1, even though function 'open' creates the file when it doesnt exist.
Thanks.
write takes a pointer to a memory buffer as the second argument, but you pass it an int
write(filee,'x',sizeof(char));
You should try something along the lines of
char c = 'x';
write(filee, &c, sizeof(char));
You are passing a character literal where write() expects a pointer to the data.
Try something like this:
const char data[] = { 'x' };
write(fille, data, sizeof data);
Also, you should check the return value of open() before relying on the file descriptor being valid.
When using API:s you're not familiar with, it's a good idea to read the manual page, and check the expected arguments against what you are using.
Also, you should enable more compiler warnings; this is something the compiler should have warned about, for sure.

Resources