Getting wrong output from reading lines in a file in c program - c

I need to get this output:
P1 0 3
P2 1 6
P3 4 4
P4 6 2
But instead I am getting this:
0 0 0
0 0 0
0 0 0
0 0 0
I am new to C programming. So, I don't know why I am getting wrong output. This is what I did. I am supposed to store each column in different variable. Because After storing them in different variable I need to do maths calculation for them.
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include <math.h>
#include <stdint.h>
#include <stdbool.h>
int main (int argc, char *argv[]) {
FILE *fptr;
fptr = fopen(argv[1], "r");
if (fptr != NULL) {
size_t i;
int SIZE = 1000;
int*x[500];
int*y[500];
int*z[500];
int ch=0;
int l;
int n=0;
char line[100];
while ((ch=fgetc (fptr))!= EOF) {
if (ch=='\n')
n++;
}
printf("Number of lines = %d\n", n);
for (l=0; l<n;++l) {
while(fgets(line,sizeof line,fptr)) {
printf("%s",line);
sscanf(line,"%d %d %d",&x[l],&y[l],&z[l]);
}
}
for (i=0; i<l;++i) {
printf("%d %d %d\n",x[i],y[i],z[i]);
}
fclose(fptr);
return 0 ;
}

I see at least 2 issues.
The fptr has gone to the end of file while counting number of lines. So rewind() the fptr after counting lines, as it has gone up to the end of file. So add rewind(fptr) after first while loop.
You do not need x, y, z as array of pointers, rather just an array. So change them to
int x[500];
int y[500];
int z[500];

Okay, lets sort this out with comments first:
#include<stdio.h>
// i dont think the following includes are nessesary for the given code
//#include<stdlib.h>
//#include <string.h>
//#include <math.h>
//#include <stdint.h>
//#include <stdbool.h>
int main (int argc, char *argv[]) {
FILE *fptr;
// i wonder a little about what youre opening here with argv[1]
// since arrays start counting at 0
// for testing and more understandability maybe just put the file
// where your code is and deliver its filename as a string?
fptr = fopen(argv[1], "r");
if (fptr != NULL) {
// whats that? you use it as a counting variable, make it int
// not size_t
size_t i;
// its not good practive to have a variable in capitals
// if you wanna make it a constant, you should define it
// at the beginning of the code, right after your includes
int SIZE = 1000;
// dont use pointers (these -> "*") here! Maybe you mix up
// dynamic array declaration (which requires using malloc() and
// no brackets like "int * dynArray;") with static arrays
// correct usage would be: int x[500]; thats it
int*x[500];
int*y[500];
int*z[500];
int ch=0;
// just a hint for more readability: use "j" instead of "l" but
// thats really up to you :D
int l;
int n=0;
char line[100];
// here you loop through your file char by char and just count
// the lines. Why dont pick the chars on the fly and actually
// write something into your defined arrays x, y, z ?
// some additional conditions (if) may do the trick
while ((ch=fgetc (fptr))!= EOF) {
if (ch=='\n')
n++;
}
printf("Number of lines = %d\n", n);
// sizeof is a function, so youre missing the parentheses
// and above that, you already know the size of your line array
// because its statically defined to hold 100 * sizeof(char)
// my suggestion: trash this entire loop and rethink the previous
for (l=0; l<n;++l) {
while(fgets(line,sizeof line,fptr)) {
printf("%s",line);
sscanf(line,"%d %d %d",&x[l],&y[l],&z[l]);
}
}
// cool loop. but there was no input to x, y, z except the first
// element of your line array, which seems to hold just a 0
// so everythings correct here, the mistake occured before
for (i=0; i<l;++i) {
printf("%d %d %d\n",x[i],y[i],z[i]);
}
//nice, thats important :)
fclose(fptr);
return 0 ;
}
i hope it helps you sort out things and may guide to a clearer question which maybe answeres itself? :D

Related

(C) generating random data using /dev/urandom and writing it into file

I'm pretty new to C, and I'm not sure what is wrong with this piece of code I have written. It is supposed to open (or create if needed) a file using a name specified and in that file write a bunch of signs taken from the /dev/urandom file. I need a precise amount of elements each one of a specified length. I need to be able to later edit that created file, but I wanted to focus on creating this generator part first. It doesn't show any errors when compiling or when I try to execute it, but still nothing happens - the file still doesn't exist anywhere. What's wrong with it?
int main(){
void generate(char str[], int a, int b);
}
void generate(char str[], int a, int b){
int n=0;
char fname[128];
strcpy(fname,str);
strcpy(fname, ".txt");
FILE *myFile = fopen(fname, "w");
FILE *randomiser = fopen("/dev/urandom", "r");
char bufor[a];
size_t result = fread (bufor, b, a, randomiser);
size_t end = fwrite (bufor, b, a, myFile);
fclose(myFile);
fclose(randomiser);
}
#edit
change the tile as someone suggested and changed a code a bit since im still trying to work it out
I forgot to mention that the whole point of this function is for it to be called in terminal as for example ./program generate data 100 100.
Here is the exact solution you asked for
There you go. I use open instead of fopen, read a certain amount of char out of /dev/urandom then write it to fd2 (the file created),
Be carefull the size of the buffer, be careful The NULL (\0) terminate the string
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
int generate(char **av)
{
int fd1 = open("/dev/urandom", O_RDONLY);
int fd2 = open(av[1], O_CREAT | O_RDWR, S_IRWXU);
int size = atoi(av[2]);
int row = atoi(av[3]);
int i = -1;
int j = -1;
if (fd1 == -1 || fd2 == -1 || size <= 0 || row <= 0 )
return (1);
char buf[size];
while (++i < row-1)
{
read(fd1, buf, size);
buf[size -1] = '\0';
write(fd2, buf, size -1);
while (++j < size)
buf[j] = '\0';
}
close(fd1);
close(fd2);
return (0);
}
int main(int ac, char **av)
{
int s;
if (ac < 4)
return (1);
generate(av);
return (0);
}
for 10 * 100 char into file 'blabla' Use with :
$~> gcc prog.c -o program
$~> ./program blabla 100 10
Will create / open the file "blabla" read 100 from /dev/uramdom and wirte to blabla
To explain what you did wrong here look :
This is a declaration of a function
void generate(int i, char *a);
This is a call to a function
generate(25, "Blablabla");
sometime when you declare a function you also instanciate it aswell
int generate(int i, char *a)
{
Operation;
operation;
return (0);
}
Declaration, and instanciation are different, let's assume i wrote funtion generate under function main in the above code example, function main would not know what is "generate" but if you declare it before main just like this it works
void generate(int i, char *a);
Here's what I made out of your source code with minimal changes
#include <stdio.h>
void generate(char basename[], size_t size);
int main(void) {
generate("foobar", 42);
}
void generate(char basename[], size_t size) {
char fname[128];
sprintf(fname, "%s.txt", basename);
FILE *myFile = fopen(fname, "w");
FILE *randomiser = fopen("/dev/urandom", "r");
char bufor[size];
size_t result = fread(bufor, 1, size, randomiser);
fwrite(bufor, 1, result, myFile);
fclose(myFile);
fclose(randomiser);
}
The problem is that your program never calls the generate() function, as #fredrik pointed out in comments. This:
void generate(char str[], int a, int b);
is a function declaration, not a call. Although it is legal to put such a declaration inside a function, it is much more conventional to put it outside and preceding the function(s) that will be doing the calling. And in this case, you could avoid using a separate declaration at all by just moving the main() function to the end, after the definition of generate().
But that still doesn't get around the fact that you need to call the function if you want it to do anything. And to call it, you will need to provide arguments. For example,
generate("random_data", 10, 4);
From your description, you'll want to use arguments determined from evaluation of command-line parameters, but that aspect would be a separate question.

C function returning different values while calling from main function

I have written a program which read values from a the file. The data in the file is in following format.
100 Full Name SomeDetails.
234 Full Name SomeDetails
Following is the program which i wrote.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAX 10
struct student
{
int rollno;
char name[20];
char course[25];
};
int main()
{
FILE *fptr;
fptr=fopen("records.txt","r");
struct student s[10];
int i=0,tstudent=0;
char che;
char line[100];
//SECTION : 1.1 -> READING NUMBER OF LINES
while(!feof(fptr))
{
che=fgetc(fptr);
if(che=='\n')
{
tstudent++;
}
}
printf("Total Lines in File = %d\n",tstudent);
fclose(fptr);
//SECTION : 1.2 -> READING RECORDS FROM FILE
fptr=fopen("records.txt","r");
char newString[20][20];
int ii,j,ctr;
j=0;
ctr=0;
for(i=0; i<tstudent; i++)
{
fgets(line,100,fptr);
printf("Value of Line %d = %s",i,line);
for(ii=0; ii<=(strlen(line)); ii++)
{
// if tab or NULL found, assign NULL into newString[ctr]
if(line[ii]=='\t'||line[ii]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j]=line[ii];
j++;
}
}
}
for(ii=0; ii < ctr; ii++)
{
printf("\n%s",newString[ii]);
}
printf("Value of ctr = %d",ctr);
fclose(fptr);
}
Above code is working fine, BUT all the code is in main function, but i want to make a separate function which can be called from main file and return me every data of file in two dimensional or one dimensional array as return value.
Any help/suggestions would be appreciated.
I tried following CODE as a separate function.. NOT WORKING.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
char readfile(int tstudent,FILE* filename)
{
//FUNCTION TO READ RECORDS FROM FILE.
FILE *fptr;
int i,k;
char line[100];
char newString[20][20];
int j=0,ctr=0;
fptr=fopen("records.txt","r");
for(i=0; i<tstudent; i++)
{
fgets(line,100,fptr);
printf("Value of Line %d = %s",i,line);
for(k=0; k<=(strlen(line)); k++)
{
// if tab or NULL found, assign NULL into newString[ctr]
if(line[k]=='\t'||line[k]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j]=line[k];
j++;
}
}
}
return newString;
}
I defined a new variable char results[] in main function.. and tried to called the function as follows
results[]=readfile(tstudent,fptr)
but when trying to read results.. its showing garbage
char readfile(int tstudent,FILE* filename)
...
char newString[20][20];
...
return newString;
That can't be a good thing, right? You define readFile to return one single character (not a pointer, just one byte) and then return an array instead. We should not be surprised the compiler complained.
If you "fix" that be redefining the return type, you still have a problem because newString is an automatic local variable. The storage (memory) it defines is undefined outside the function.
The easiest way for a function to populate a structure (or array) in C is for the caller to pass it as a function parameter. So you wind up with something more like:
int readfile( FILE* input, char newString[][20], int tstudent )
where newString is defined the same way as you have it, but by the caller, not in readfile. Cf. the stdio functions like fgets; most of them require the caller to define the buffer they read into.
I'll just point out a few more mistakes.
Whenever you call a function -- especially an I/O function -- check for errors. You may want to read tstudent records, but how many are there? If you ask for 5 and find only 1, what then? Your read loop must test for end-of-file, and readfile must return the number of records read, else the caller will never know. Compare with how fread(3) works. Those Unix guys knew a thing or two about how to define a function!
Now your function looks something like this:
int readfile( FILE* input, char newString[][20], int tstudent ) {
char line[100], *s;
int i=0;
for( ; i < tstudent && (s = fgets(line, sizeof(line), input)) != NULL; i++ ) {
/* do stuff with line */
}
/* check for EOF/error if s is NULL, and report */
return i;
}

Why isn't my code reading the correct integers from a file?

So after playing a little bit with Craig Estey's answer, I managed to get the following piece of code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char **argv){
char *filename = argv[1];
if(filename == NULL) {
printf("Please specify a filename.\n");
exit(1);
}
FILE *fi = fopen(filename,"r");
printf("Finding size...\n");
int size = 0;
while(fscanf(fi,"%*d") != -1) size++;
rewind(fi);
int numbers[size];
while(fscanf(fi,"%d",&numbers[size]) != 1);
fclose(fi);
printf("Size of array: %d\n\n", size);
int idx=0,idx2=1,idx3=1,idx4=1;
printf("Elements: \n");
while (idx < size){
printf("%d\n",numbers[idx]);
idx++;
}
int maximum = numbers[0];
while (idx2 < size){
if (numbers[idx2] > maximum){
maximum = numbers[idx2];
}
idx2++;
}
printf("\nMax: %d\n",maximum);
int minimum = numbers[0];
while (idx3 < size){
if (numbers[idx3] < minimum){
minimum = numbers[idx3];
}
idx3++;
}
printf("Min: %d\n",minimum);
int sum = numbers[0];
while (idx4 < size){
sum = sum + numbers[idx4];
idx4++;
}
printf("Total: %d\n",sum);
}
Problem is, now it executes without halting, but still doesn't provide the right answer. My 'abcd.txt' file contains the following numbers:
5564
4324
863
98743
However, my result after executing reader.c is:
./reader abcd.txt
Finding size...
Size of array: 4
Elements:
0
0
1384783917
32713
Max: 1384783917
Min: 0
Total: 1384816630
Why is that, now? I cannot find why is it different than in the answer below. If I execute the exact code in the answer, it does return the right answer. Thanks in advance.
This is prefaced by my top comments.
You can't do: printf(numbers[idx2]); (i.e. the first argument has to be a format string). So, do: printf("%d\n",numbers[idx2]);
Doing sizeof(numbers) / sizeof(int) does not give an accurate count of the number actually filled in. It gives the maximum which will have garbage values at the end.
Because, there were so many errors, I couldn't list them all. I had to completely refactor your code. Just compare it in detail to yours to see the difference. You'll learn much more and more quickly than trying to patch what you already have.
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
long int
findSize(char *filename)
{
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("findSize: unable to open file '%s' -- %s\n",
filename,strerror(errno));
exit(1);
}
fseek(fp, 0L, SEEK_END);
long int res = ftell(fp);
fclose(fp);
return res;
}
int
main(int argc, char **argv)
{
char *filename = argv[1];
if (filename == NULL) {
printf("please specify a filename\n");
exit(1);
}
printf("findSize\n");
int numbers[findSize(filename)];
printf("scanf\n");
FILE *fi = fopen(filename,"r");
int size = 0;
while (1) {
if (fscanf(fi,"%d",&numbers[size]) != 1)
break;
printf("scanf: %d\n",numbers[size]);
++size;
}
fclose(fi);
printf("size: %d\n",size);
for (int idx2 = 0; idx2 < size; ++idx2)
printf("%d\n",numbers[idx2]);
int maximum = numbers[0];
for (int idx3 = 1; idx3 < size; ++idx3) {
if (numbers[idx3] > maximum)
maximum = numbers[idx3];
}
printf("Max: %d\n", maximum);
int minimum = numbers[0];
for (int idx4 = 1; idx4 < size; ++idx4) {
if (numbers[idx4] < minimum)
minimum = numbers[idx4];
}
printf("Min: %d\n", minimum);
int sum = 0;
for (int idx5 = 0; idx5 < size; ++idx5)
sum = sum + numbers[idx5];
printf("Total: %d\n", sum);
return 0;
}
UPDATE:
First of all, thanks a lot for your work. Looking at your code (I cannot call it anymore my code as it's completely different)
Yes, it was intended as a guide for you to write/rewrite your own code, which you've done.
I see that the findSize function is mostly irrelevant.
It is technically correct, but would allocate [much] more space than was needed.
I tried to put another fscanf instead of calling a findSize function, but I don't know how this function works exactly.
Good for you in figuring out this alternate sizing algorithm.
Let me see if I get it: If there is a third argument, it stores each read element into the third argument (which should be a variable). But if there is no third element, and you put an * in the second argument, it doesn't store the read elements anywhere. Am I right?
Believe it or not, I don't use fscanf too much as it can be slow, so I'm not familiar with some of the more esoteric options. I've tested your new sizing loop and it appears to work, so I think your analysis may be correct.
Also, we could simply introduce an extra scalar int variable and do:
int size = 0;
while (1) {
int val;
if (fscanf(fi,"%d",&val) != 1)
break;
++size;
}
However, you're actual second fscanf loop that is used to read in the numbers will not work:
while (fscanf(fi, "%d", &numbers[size]) != 1);
This puts all numbers in the same index, namely size, which is one beyond the end of the numbers array, so this is undefined behavior.
Also, the loop condition is reversed from what it should be, so only one number would be filled in.
To fix this, we need an additional index variable and need to change the sense of the while loop:
int idx0 = 0;
while (fscanf(fi, "%d", &numbers[idx0]) == 1)
++idx0;
After this change, the rest of your updated code [min/max/sum] works fine.
Some notes on style:
As you noticed, my original posted code was a bit different (e.g. replacing while loops with for loops).
But, one thing I didn't do was reuse the index variable. That is, there isn't a need to have separate ones for each loop. They could all be changed to a single idx variable.
Using different symbols isn't wrong, and can add to clarity. But, idx, idx1, idx2 aren't as descriptive as they could be.
If you'd like to keep separate variables, I'd suggest more descriptive names such as: inpidx, minidx, maxidx, and sumidx

Creating an array with unknown size of input files

I newer in C language. I could not solve my problem. I have a input file, let's say input.txt. We know there are 4 column on every line. Nevertheless, we do not know how many lines are there. I give you sample input.txt:
Student,James,12,65
Teacher,Jane,23,60
Teacher,Michael,30,75
Student,Erric,15,73
First column can be 2 different things like student or teacher. 2nd column will be unique. No repeated names. 3rd column will be ages of the person's. 4th column will be weights. Also, I am trying to make 2D array. So, my goal is:
arrName = {{Student, James, 12, 65}, {Teacher,Jane,23,60}, {Teacher,Michael,30,75}, {Student, Erric, 15,73}}
I am trying to create like this array. The array must be dynamically. because we do not know how many lines are there. I could not split the every line by commas. I have tried strdot. how can I parse the lines with comma, and add them into 2D array? Also, I got confused about pointers. While creating 2D array, do we have to use like char **arrPtr;? Or using like *arrPtr is enough for creating 2D array?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define COLUMN 4 //We know that there are 4 column in chars.txt file.
int main(int argc, char const *argv[]) {
char *arrName;
int nameLines;
arrName = (char *) malloc( sizeof( char ) );
FILE *FileName;
FileName = fopen(argv[1], "r");
if (FileName == NULL) {
printf("The Name file could not open!\n");
exit(0);
}
else{
char c;
while ( (c == fgetc(FileName)) != EOF ) {
if (c == '\n') {
nameLines++;
}
}
printf("%d\n", nameLines);
}
return 0;
}
I could not continue after else statement. Can you help me?
You got a bunch of errors in your code like this for example.
while ( (c == fgetc(FileName)) != EOF ) { -> Comparison of constant -1 with boolean expression is always true
So let's start fresh. This is how I would read a comma separated file and dynamically allocate memory to an array of ´read´ objects. It's actually less lines of code then you would expect.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define COLUMNS 4
#define MAX_STRING_LENGTH 100 //Enter the maximum characters allowed as profession and name
typedef struct theDAta{
char type[MAX_STRING_LENGTH+1];
char name[MAX_STRING_LENGTH+1];
unsigned int age;
unsigned int weight;
}theData;
int main(int argc, char const *argv[]) {
theData* allDataPtr=malloc(1); //Pointer to all entries
theData currentData; //The current read data
int currentBlock=0; //the index currently 'active'
FILE *fp = fopen(argv[1], "r");
if (!fp) {
printf("The file you provided can't be read!\n");
exit(EXIT_FAILURE);
}
while (fscanf(fp, "%[^,],%[^,],%d,%d\n", currentData.type, currentData.name,&currentData.age,&currentData.weight) == COLUMNS) {
allDataPtr=realloc(allDataPtr, sizeof(theData)*(currentBlock+1));
if (!allDataPtr) {exit(EXIT_FAILURE);} //Memory allocation failure. Ok so here i lost my pointer to the previous memory.. However we let the OS garbage collect us.
memcpy(allDataPtr+currentBlock++, &currentData, sizeof(currentData));
}
for (int x=0; x<currentBlock; x++) {
printf("Profession: %s\nName: %s\nAge: %d\nWeight: %d\n\n",allDataPtr[x].type,allDataPtr[x].name,allDataPtr[x].age,allDataPtr[x].weight);
}
fclose(fp);
free(allDataPtr);
return 0;
}
So what I do is to create a struct containing the stuff I want to populate from the file. Then I populate that object and extend the memory with the size of that object and then copy the read data to the end of that memory block.. That's basically it... Hope you get great grades :) !!
/Anders
EDIT
Was a bit bored this evening, so let's shave the code... And humm, well. This is not part of my official answer :-) but you could bling it like this (it's actually also skipping one layer of memory copy :) and the engine is 3 lines of C code if you define a line of C code delimiter as ';'->
typedef struct j{
char t[MAX_STRING_LENGTH+1];
char n[MAX_STRING_LENGTH+1];
unsigned int a;
unsigned int w;
}j;
int main(int argc, char const *argv[]) {
j* g;
int l=0;
FILE *h;
if((!(h=fopen(argv[1],"r"))||(!(g=malloc(sizeof(j))))))exit(-1);
while(fscanf(h,"%[^,],%[^,],%d,%d\n",g[l].t,g[l].n,&g[l].a,&g[l].w)==COLUMNS)if(!(g=realloc(g,sizeof(j)*(++l+1))))exit(-1);
for(int x=0;x<l;x++)printf("Profession: %s\nName: %s\nAge: %d\nWeight: %d\n\n",g[x].t,g[x].n,g[x].a,g[x].w);
fclose(h);
free(g);
return 0;
}

Segmentation fault with arrays and pointers

I have a segmentation fault...i'm not sure what's causing it. Also, when passing the member pname into the function get_names, am I doing this correctly, or is there a better way of doing this?
#include <stdio.h>
#define MAX_NAME 20
#define MAX_PLAYRS 16
typedef struct {
char pname[MAX_NAME];
int runs;
char how_out;
} Team_t;
Team_t player[MAX_PLAYRS];
Team_t *player_ptr[MAX_PLAYRS];
void get_names (int count, char *str);
int main (void) {
int i;
for (i = 0; i < MAX_PLAYRS; i++) {
get_names(i, &(*player[i].pname));
printf("Player: %s\n", player[i].pname);
}
}
void get_names (int count, char *str) {
FILE *inp;
char status;
inp = fopen("teamnames.rtf", "r");
status = fscanf(inp, "%s", str);
if (status == EOF) {
count = MAX_PLAYRS;
}
}
With your code unchanged, I get a segmentation fault if the file can't be opened properly (i.e. it's unreadable due to permissions, or it simply does not exist).
Here's a modified version of you function get_names():
void get_names(int count, char *str)
{
FILE *inp;
inp = fopen("teamnames.rtf", "r");
if (inp == NULL) {
perror("Failed");
return;
}
fgets(str, MAX_NAME, inp);
fclose(inp);
}
This would still read the first name 16 times, but it would tell you why it didn't manage to open the file. To read the next name from the file (rather than repeatedly the first name), open (and close) the file in the main() function instead.
Also, you might as well call get_names() like so:
get_names(i, player[i].pname);
No need to do that &(*...) thing you're doing.
And, finally, I hope that the teamnames.rtf file is not actually an RTF file, but a simple text file with a name on each line.
The problem comes from this line:
get_names(i, &(*player[i].pname));
Understanding pointers and dereferencing is one of the biggest adjustments to learning C if you are switching from another language. You're doing it wrong, and I think you should seek out a tutorial on the subject. Try http://www.cplusplus.com/doc/tutorial/pointers/ as a starting point.
Get a debugger to tell you what is wrong. Compile the code with debugging enabled (see you man page for your compiler) and run something like this:
gdb a.out core
Then you should be able to see which line made the code core dump. You could use idb as well, if you have the intle compiler installed. This is, of course, on *nix. If you are talking windows, use the VS debugger.
In addition do NOT use fscanf as it is unsafe. Use fgets instead.
There are many strange things. First thing is, it seems like the names are in a file, but what you are doing is in every iteration of your for loop, you call get_names which opens the file again, that is goes to the beginning of the file and you read the same name over and over again.
That is if you closed the file. Since you haven't closed the file, the file is already open and you keep reopening it (which could be the cause of your problem)
Another thing is, how can
if (status == EOF) {
count = MAX_PLAYRS;
}
Give you the current count? Regardless of the count of the players in the file, you are just setting it to MAX_PLAYERS.
Another thing is that count is an input to the function that is not a pointer, so setting it does not change the value outside the function (which is what I assumed you wanted).
Here is how I would do it with minimum change to your code:
#include <stdio.h>
#define MAX_NAME 20
#define MAX_PLAYRS 16
typedef struct {
char pname[MAX_NAME];
int runs;
char how_out;
} Team_t;
Team_t player[MAX_PLAYRS];
Team_t *player_ptr[MAX_PLAYRS];
void get_names (int count, char *str, FILE *inp);
int main (void) {
FILE *inp;
int i;
int count;
inp = fopen("teamnames.rtf", "r");
for (i = 0; i < MAX_PLAYRS; i++) {
get_names(&count, player[i].pname, inp);
printf("Player: %s\n", player[i].pname);
}
}
void get_names (int *count, char *str) {
char status;
status = fscanf(inp, "%s", str);
if (status == EOF) {
*count = MAX_PLAYRS;
}
}
Here is how I would do it more concisely:
#include <stdio.h>
#define MAX_NAME 20
#define MAX_PLAYRS 16
typedef struct {
char pname[MAX_NAME];
int runs;
char how_out;
} Team_t;
Team_t player[MAX_PLAYRS];
Team_t *player_ptr[MAX_PLAYRS];
int get_names (Team_t *team);
int main (void) {
get_names(player);
}
int get_names (Team_t *team) {
int i = 0;
FILE *inp;
inp = fopen("teamnames.rtf", "r");
while (i < MAX_PLAYRS && !feof(inp) {
fscanf(inp, "%s", team[i].pname);
printf("Player: %s\n", player[i].pname);
}
}
Note that the problems with fscanf, checking array boundaries etc are not the concern of this solution, but this rather gives you the idea of what to do not a code for you to copy-paste.

Resources