Searching A File For Specific Names in C? - c

I'm a relatively new programmer and I'm working on a school project. Right now what I'm trying to do is read through a file and get it to check if two characters interact(i.e they appear on the same line).
Right now I haven't too much done and I'm really asking more for ideas rather than code. How would one go about doing something like this? I had a few ideas but none of them actually worked in practise so as of now, this is all I really have done and working:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Characters{
char names[65][50]; //This is the names array
char compnames[65][50]; //This is a duplicate to compare the arrays of characters
int relations;
};
void NameFun();
int main(){
NameFun();
}
void NameFun(){
int i=0, choice;
struct Characters c;
FILE *fp = NULL;
fp = fopen("MisNames.txt", "r");
for(i=0; i<65; i++){
fgets(c.names[i], sizeof(c.names[i]), fp); //Gets each name and stores it as an element of an array
strcpy(c.compnames[i], c.names[i]); //For the duplicate, copying the elements
}
/*The rest of this was for testing purposes and has no real relevance
printf("What number name would you like to know about?\n");
scanf("%d", &choice);
choice = choice--;
printf("\t\t\t%s\n\n", c.names[choice]);
fclose(fp);
}*/

Related

How do I properly call the function I created to the main?

So I suck with functions and need to debug this. Im pretty sure the function ToPigLating does its job well at converting. However I just need help calling the function ToPigLatin inside of my main function. But when I try doing that I just get a bunch of error codes.
#include <stdlib.h>
#include <string.h>
#define LEN 32
char* ToPigLatin(char* word[LEN]){
char word[LEN];
char translation [LEN];
char temp [LEN];
int i, j;
while ((scanf ("%s", word)) != '\0') {
strcpy (translation, word);
//just pretend I have all the work to convert it in here.
} // while
}
int main(){
printf("Enter 5 words: ");
scanf("%s", word);
ToPigLatin();
}```
Roughly, variables only exist within the function they're declared in. The word in ToPigLatin exists only within ToPigLatin. It is not available in main. This lets us write functions without worrying about all the rest of the code.
You need to declare a different variable in main, it can also be called word, to store the input and then pass that into ToPigLatin.
Let's illustrate with something simpler, a function which doubles its input.
int times_two(int number) {
return number * 2;
}
We need to give times_two a number.
int main() {
// This is different from "number" in times_two.
int number = 42;
// We have to pass its value into time_two.
int doubled = times_two(number);
printf("%d doubled is %d\n", number, doubled);
}
Your case is a bit more complicated because you're working with input and memory allocation and arrays. I'd suggest just focusing on arrays and function calls for now. No scanf. No strcpy.
For example, here's a function to print an array of words.
#include <stdio.h>
// Arrays in C don't store their size, the size must be given.
void printWords(const char *words[], size_t num_words) {
for( int i = 0; i < num_words; i++ ) {
printf("word[%d] is %s.\n", i, words[i]);
}
}
int main(){
// This "words" variable is distinct from the one in printWords.
const char *words[] = {"up", "down", "left", "right"};
// It must be passed into printWords along with its size.
printWords(words, 4);
}
ToPigLatingToPigLating function expects to have a parameter like ToPigLating("MyParameter");
Hello there icecolddash.
First things first, there are some concepts missing. In main section:
scanf("%s", word);
You're probably trying to read a string format and store in word variable.
In this case, you should have it on your declaration scope. After some adjustment, it will look like this:
int main(){
char word[LEN];
As you defined LEN with 32 bytes maximum, your program will not be allowed to read bigger strings.
You're also using standard input and output funcitions as printf, and so you should ever include stdio.h, thats the header which cointains those prototypes already declared, avoiding 'implicit declaration' compiling warnings.
Next issue is how you're declaring your translation function, so we have to think about it:
char* ToPigLatin(char* word[LEN])
In this case, what you wrote:
ToPigLatin is a funcion that returns a char pointer, which means you want your function to probably return a string. If it makes sense to you, no problem at all. Although we got some real problem with the parameter char* word[LEN].
Declaring your variable like this, assume that you're passing an array of strings as a parameter. If I got it right, you want to read all five words in main section and translate each one of them.
In this case I suggest some changes in main function, for example :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 32
#define MAX_WORDS 5
char *globalname = "translated";
char* ToPigLatin(char* word){
char *translation = NULL;
//Translation work here.
if ( !strcmp(word, "icecolddash") ){
return NULL;
}
translation = globalname;
return translation;
}
int main(){
char word[LEN];
char *translatedword;
int i;
printf("Enter 5 words: \n");
for ( i=0; i < MAX_WORDS; i++ ){
fgets(word, sizeof(word), stdin);
strtok(word, "\n"); // Just in case you're using a keyboard as input.
translatedword = ToPigLatin(word);
if ( translatedword != NULL ){
//Do something with your translation
//I'll just print it out as an example
printf("%s\n", translatedword);
continue;
}
// Generic couldn't translate message
printf("Sorry, I know nothing about %s\n", word);
}
return 0;
}
The above code translate every word in a fixed word "translated".
In case of reading the exact input "icecolddash", the program will output a generic error message, simulating some problem on translation process.
I hope this help you out with your studies.
There are a few things that I see.
#include <stdio.h>
#include <stdlib.h>
char* ToPigLatin(char* word){
printf(word);
return word;
}
int main(){
printf("Enter 5 words: ");
// declare the variable read into by scanf
char * word = NULL;
scanf("%s", word);
//Pass the variable into the function
ToPigLatin(word);
// Make sure you return an int from main()
return 0;
}
I left some comments in the code with some specific details.
However, the main thing that I would like to call out is the style of the way you're writing your code. Always try to write small, testable chunks and build your way up slowly. Try to get your code to compile. ALWAYS. If you can't run your code, you can't test it to figure out what you need to do.
As for the char ** comment you left on lewis's post, here is some reading you may find useful in building up your intuition:
https://www.tutorialspoint.com/what-does-dereferencing-a-pointer-mean-in-c-cplusplus
Happy coding!

Fread function and files

I have to make a program which will print the name and the score of a student found on a text file. The text file itself will follow this format:
number of students (int)
score name (of student number one)
score name (of student number two)
So for example, the students.txt file you will see I am using for this program should be something like this:
2
45 George
23 John
The reading part of the program (for the structures) should be done using fread. I have tried what you will see below and the problem is that when I run the program the console just remains blank. Note that the program is not complete yet, since I am trying to learn how a few things work first (for example I am only trying to print the scores of the student just so I can see whether I know what I am doing) before doing it properly and I know some parts like checking for NULL return are missing. I am also wondering whether since I am using fread the txt file should be considered binary or not.
Here is what I have tried:
#include <stdio.h>
#include <stdlib.h>
#define FILENAME students.txt
#define MAX 50
typedef struct st {
float score;
char name[MAX];
} student;
void read(FILE *fp, student *p, int size);
int main()
{
int number;
student *ptr;
FILE *ifp;
ifp = fopen("FILENAME", "rb");
fscanf(ifp, "%d", &number);
ptr = (student *)malloc(number * sizeof(student));
read(ifp, ptr, number);
}
void read(FILE *fp, student *p, int size)
{
int num;
fscanf(fp,"%d", &num);
fread(p, sizeof(student), size, fp);
for(int i=0; i<size; i++)
printf("%f", p[i].score);
}
You are opening a file named "FILENAME", not "students.txt", which is why your command line is remaining blank. Change
#define FILENAME students.txt
into
#define FILENAME "students.txt"
and
fopen("FILENAME", "rb");
into
fopen(FILENAME, "r");
Furthermore, fread requires that the caller knows the exact size of the elements they are reading, but since the student names have a variable length, this is not the case. You should use fgets instead. You can read more about fgets here.
fread should only be used in the case of binary input/output, usually memory blocks (arrays or structs) that have a size known to the caller.

Compare Strings with if statenent in C [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 4 years ago.
I'm a beginner in c programming and i'have come to a point (pretty ridiculous) that i'm stuck at an if statement between two strings.
In this program, i want the user to input a lesson of a student saved in a structure, then it should search for students with the same lesson and print them on screen.
My problem is at if statement, for some reason (memory address maybe?) when i type the same characters, it sees them for different strings.
The code just "skips" the if part. Although it works when i declare if(record[0].lesson!="maths") for instance.
i have tried lots of things such as strcmp,
if (record[0].lesson==record[1].lesson)
if(record[0].lesson=="maths")... and other.
I would highly appreciate it if you could help me. thank you very much.
# include <stdio.h>
# include <string.h>
typedef struct student{
char name[10];
char lesson[10];
}students;
int main()
{
students record[10];
char less;
strcpy(record[0].name,"James");
strcpy(record[0].lesson,"maths");
strcpy(record[1].name,"John");
strcpy(record[1].lesson,"maths");
strcpy(record[2].name,"Harry");
strcpy(record[2].lesson,"C/C++");
printf("Give Lesson\n");
scanf("%s",less);
for(int i=0;i<3;i++){
if(less==record[i].lesson)
printf("%s\n",record[i].name);}
return 0;
}
You want this:
better formatting
less declared correctly as char less[10];
using strcmp for string comparision instead of ==
#include <stdio.h>
#include <string.h>
typedef struct student{
char name[10];
char lesson[10];
} students;
int main()
{
students record[10];
char less[10];
strcpy(record[0].name, "James");
strcpy(record[0].lesson, "maths");
strcpy(record[1].name, "John");
strcpy(record[1].lesson, "maths");
strcpy(record[2].name, "Harry");
strcpy(record[2].lesson, "C/C++");
printf("Give Lesson\n");
scanf("%s", less);
for (int i = 0; i < 3; i++) {
if (strcmp(less, record[i].lesson) == 0)
printf("%s\n",record[i].name);
}
return 0;
}
There is still much room for improvement.

How to properly use fscanf and fgets to read from file

I'm new at programming in C (it's my first language) and I'm not so good at english, so sorry for the grammar... By the way, I was wondering if you could help me with this:
I have to read from file the components of the array, setting them as part of it and see them as output in the screen.
I created a file with this informations:
Rossi,Mario,M,mariorossi#gmail.com,3923333332,Portiere
Bianchi,Giuseppe,M,giuseppebianchi#gmail.com,3470000021,Attaccante
Ferrari,Anna,F,annaferrari#gmail.com,3466482645,Attaccante
Romano,Antonio,M,antonioromano#gmail.com,3450394672,Centrocampista
and trying to coding I ended up with this:
#include <stdio.h>
#include <stdlib.h>
struct dati_giocatori {
char cognome[20];
char nome[20];
char genere[20];
char email[20];
int telefono;
char ruolo[20];
};
typedef struct dati_giocatori GIOCATORE;
void lettura(FILE *file, GIOCATORE *vettore, int dim);
void stampa(GIOCATORE *vettore, int dim);
int main (){
FILE *file;
GIOCATORE *vettore;
int dim;
vettore=(GIOCATORE*)malloc(dim*sizeof(GIOCATORE));
printf("how many players do you want to see?");
scanf("%d",&dim);
file=fopen("Giocatori.txt","r");
lettura(file,vettore,dim);
stampa(vettore,dim);
system("pause");
return 0;
}
void lettura(FILE *file, GIOCATORE *vettore, int dim){
int i=0;
if(file){
while(!feof(file) && i<dim){
fscanf(file,"%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],[^\n]", vettore[i].cognome,vettore[i].nome,vettore[i].genere,vettore[i].email,&vettore[i].telefono,vettore[i].ruolo);
i++;
}
}
else{
printf("Error.");
}
}
void stampa(GIOCATORE *vettore, int dim){
int i=0;
while(i<dim){
printf("%s,%s,%s,%s,%d,%s\n", vettore[i].cognome,vettore[i].nome,vettore[i].genere,vettore[i].email,vettore[i].telefono,vettore[i].ruolo);
i++;
}
}
but it does not work very well. I know I have some problems with the fscanf (probabily), and I wanted to know if the malloc is used correctly... Could you help me? Where are the errors I make? How can I solve them? How should the code be using a fgets instead of fscanf? Am I using the delimitators in the right way?
Ok, thank you very much for replying, I'll treat the 10-digit phone number with a long variable, but I still don't get how I should correctly use the fscanf. It's the first time with delimitators, and this confuse me. My format specifiers are "%s,%s,%s,%s,%ld,%s", right? but how should I put them in the fscanf? What have I to write after the parameter "file" in the fscanf?
fscanf(file,"%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],[^\n]",...
Your format specifiers are not correct; if you tell fscanf that the data to read is comma-separated, which you do with the commas outside the brackets, you don't need to specify what you put inside ([^,]), and you're missing format specifiers. Try to provide fscanf the same format you gave to printf in the stampa function. Be careful: an integer variable would not hold correctly a 10-digit phone number, use a long variable or treat it like a string as well.
On the other hand, fgets would read the whole line into a string buffer as it does not accepts a format specifier, so you would end up having a one string only, containing the entire line, then you should parse it with something like sscanf in the same way you should use fscanf.

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);.

Resources