I have been looking around for a solution but cannot seem to find a solution to my question so I will ask it. I am working in C and am reading in a .txt and taking all the values and storing them in an array then doing various tasks with them. Now my problem is that no matter what I do I cannot get file pointer I create to point to the file for some reason. I have done this for projects in the past and have compared my code then to the current one and cannot see the issue. The filename needs to be read in from the command line as well. I think there is something wrong with what I'm passing through the command line but am not sure. I have stepped through and the filename is being passed correctly but when it tries to open I get a null pointer so there is just something I'm missing.
The text file will contain a series of numbers, the first number will be the number of numbers in the file after that first number. (So if the number is 10 then there will be ten numbers after 10 is read in) after that first number the remaining numbers will be 0-9 in a random order.
Below is my current chunk of code only involving reading of the file and storing its data. (I already know the array will be of size 10 which is why the array is declared with that size.)
int main(int argc, char *argv[])
{
char* filename = "numbers.txt";
int arr[10];
int numElem;
int indexDesired = 0;
FILE *fp;
fp = fopen(filename, "r"); // open file begin reading
if (!fp)
{
printf("The required file parameter name is missing\n");
system("pause");
exit(EXIT_FAILURE);
}
else
{
fscanf(fp, "%d", &numElem); //scans for the first value which will tell the number of values to be stored in the array
int i = 0;
int num;
while (i <= numElem) //scans through and gets the all the values and stores them in the array.
{
fscanf(fp, "%d", &num);
arr[i] = num;
i++;
}
fclose(fp);
}
}
***note: My sort and swap method work perfectly so I have omitted them from the code as the error happens before they are even called.
you said,
The filename needs to be read in from the command line as well.
However, you are using:
char* filename = "numbers.txt";
and
fp = fopen(filename, "r"); // open file begin reading
No matter what you are passing in the command line, the file you are trying to open is "numbers.txt".
Things to try:
Use the full path name of "numbers.txt" instead of just the name of the file.
char* filename = "C:\\My\\Full\\Path\\numbers.txt";
If that doesn't work, you will probably have to deal with permissions issues.
Pass the file name from the command line, using the full path. That should work if there are no permissions issues.
if ( argc < 2 )
{
// Deal with unspecified file name.
}
char* filename = argv[1];
Pass the relative path of the file name. If you are testing your program from Visual Studio, you have to make sure that you use the path relative to the directory from where Visual Studio launches your program.
while (i <= numElem)
should be
while (i < numElem)
Because in fscanf(fp, "%d", &numElem); you are scanning the number of elements.
Notice that the array in C starts from 0, so if say numElem is 10 arr[10] does not exist which can be harmful because arr goes from arr[0] to arr[9]
Also, you should check if numElem is lower than 10 before the while(i < numElem) loop.
Related
I am setting a pointer to pointer array of variables that will open the files and count the words. The issue I am having is how to print the file name in the output. The counting of the words work (minus a few small accounting for double spaces and such).
The files are entered as command line arguments. Here is the code:
FILE **Files = malloc(sizeof(FILE *) * (count)); //Array of file pointers
for (i = 0 ; i < count ; i++)
{
Files[i] = fopen(argv[i + 1], "r");
}
for (i = 0 ; i < count ; i++)
{
wordCount = countWords(Files[i]);
printf("File %s: number of words is: %d\n", Files[i], wordCount);
}
I have left out the error checking on if the fopen == NULL to keep it short. I have tried *Files[i], *(&Files[i]) and a few others in an attempt to print out the contents of the variable. Is there a way to print out a FILE * varible as a string?
Since argv[i + 1] is the filename, you need to print argv[i + 1]. You don't want to print Files[i] since it is not a pointer to the filename or anything related in any way to the filename.
You may not be aware of this, but a filename does not uniquely identify a file. A file can have no name at all (for example, if it is removed from the only directory it is in while it's open) or can have more than one name (for example, if it's hard linked into multiple directories). Trying to go from the file to the filename is not simple and something you should only do if you have some specific reason.
I'm trying to do a substring search using sys call where I open a file from the command line, and compare the following command line arguments to the file. I want to output the number of occurrences of each substring. For example, if I wrote ./a.out filename aa b I am looking for the number of times aa and b occurs in filename.
My code so far
for(int num = 4; num < argc; num++)
{
int fp = open (argv[1], O_RDONLY);
int sizeofbar = strlen(argv[1]);
char *buf = (char*)malloc(sizeofbar+1);
int count = 0; //counter for output
char* string2 = argv[num];
int sizeofcompare = strlen(string2);
read(fp, buf, sizeofcompare);
while (strstr(buf, string2) != NULL)
{
count++;
buf++;
}
I think you need to do some initialization before entering your loop. Perhaps you want to take the first argument off first:
filename = argv[0];
argv++;
argc--;
int fp = open(...
Next, I'd pre-process the rest of the arguments to build a data structure to store it. You can use the argc value to determine how many words you'll need to track.
counts = (int *)calloc(argc, sizeof(int));
Note that this will initialize the values to zero for you too.
With everything setup, then I'd read through the entire file contents and compare to the strings. The trick is in comparing multiple different length strings at once. A simple yet inefficient method is to read the entire file contents in and then loop using strstr for each word that follows the filename. Another method would be mapping the file's contents into memory and scanning it directly (letting the operating system do the heavy lifting).
I am trying to read a txt file with following contents:
test.txt
3,4
5,6
7,8
each pair is in one line. I want to put these values in an array. But I want the array size to adjust based on number of pairs in the test txt.
So I calculated the number of lines available in the txt file until EOF and assigned the number of lines to the array to assign the sizeof the array.Then when I try to read the file using fscanf I get some weird numbers which is not even part of this txt file like 2342,123123.
Here is my code:
#include <stdio.h>
int main(int argc , char **argv)
{
FILE *pf;
int k;
int counter=0;
int c;
pf = fopen("test.txt", "r");
if(pf==NULL)
{
printf("its nuull");
}
else
{
do
{
c=fgetc(pf);
if(c=='\n')
counter++;
}while(c!=EOF);
printf("counter value is = %d\n", counter);
int b[counter][2];
for(k=0;k<counter;k++)
{
fscanf(pf,"%d, %d" ,&b[k][0],&b[k][1]);
printf("%d,%d\n" ,b[k][0],b[k][1]);
}
}
fclose(pf);
}
I think you need to call:
rewind(pf);
after displaying your counter value.
This will reset the file pointer to the start of the file.
The issue is probably that the current file pointer is pointing at the end of the file. You need to read from the begining of the file now, so you need to do something like:
rewind(pf);
There are other mechanisms - for instance fseek or fsetpos, but rewind is what I would use here.
You might also check the return from fscanf - this will return the number of input items assigned. If this isn't 2 (in your case) then something went wrong.
So I am trying to write a C code that takes in a file name as the argument and reads the file and stores it into an array. I have tried but failed epically :(
Can anyone please point me in the right direction? Here is what I came up with (I know it may be completely off track :/ )
#include <stdio.h>
int main (int argc, char *argv[]) {
char content[500];
int k=0;
FILE* inputF;
inputF = fopen("argv[0]", "r");
do {
fscanf(inputF, "%c", &content[k]);
k++;
} while (content[k] != EOF );
return 0;
}
You passed "argv[0]" string to fopen, I'm sure that isn't the name of you file you are trying to open.
You should pass a pointer to a string that contains the file name.
inputF = fopen(argv[1], "r");
Also note the usage of argv[1] not argv[0].
argv[0] contains the full filepath and name of the executable and argv[1] the first string entered as command line parameter.
A couple of points to help get you started:
argc is the number of arguments, and the first argv pointer is the name of the executable file. The second is what you want.
You have to check that your file pointer is valid before trying to use it.
Maybe look at using fgetc to read each character, and test for EOF.
You need to check that you don't overrun your content buffer.
If you're stuck, here's an example of a main loop using a do while:
do {
ch = fgetc(fp);
content[a] = ch;
a++;
} while (ch != EOF && a < 500);
This will store an EOF (if found) in your array.
Im currently learning C through random maths questions and have hit a wall. Im trying to read in 1000 digits to an array. But without specifiying the size of an array first i cant do that.
My Answer was to count how many integers there are in the file then set that as the size of the array.
However my program returns 4200396 instead of 1000 like i hoped.
Not sure whats going on.
my code: EDIT
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
FILE* fp;
const char filename[] = "test.txt";
char ch;
int count = 0;
fp = fopen(filename, "r");
if( fp == NULL )
{
printf( "Cannot open file: %s\n", filename);
exit(8);
}
do
{
ch = fgetc (fp);
count++;
}while (ch != EOF);
fclose(fp);
printf("Text file contains: %d\n", count);
return EXIT_SUCCESS;
}
test.txt file:
731671765313306249192251196744265747423553491949349698352031277450632623957831801698480186947885184385861560789112949495459501737958331952853208805511
125406987471585238630507156932909632952274430435576689664895044524452316173185640309871112172238311362229893423380308135336276614282806444486645238749
303589072962904915604407723907138105158593079608667017242712188399879790879227492190169972088809377665727333001053367881220235421809751254540594752243
525849077116705560136048395864467063244157221553975369781797784617406495514929086256932197846862248283972241375657056057490261407972968652414535100474
821663704844031998900088952434506585412275886668811642717147992444292823086346567481391912316282458617866458359124566529476545682848912883142607690042
242190226710556263211111093705442175069416589604080719840385096245544436298123098787992724428490918884580156166097919133875499200524063689912560717606
0588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
Any help would be great.
You forgot to initialize count, so it contains random garbage.
int count = 0;
(But note that with this change it's still not going to work, since %d in a scanf format means read as many digits as you find rather than read a single digit.)
Turn on your compiler's warnings (-Wall), it will tell you that you didn't initialize count, which is a problem: it could contain absolutely anything when your program starts.
So initialize it:
int count = 0;
The other problem is that the scanfs won't do what you want, at all. %d will match a series of digits (a number), not an individual digit. If you do want to do your counting like that, use %c to read individual characters.
Another approach typically used (as long as you know the file isn't being updated) is to use fseek/ftell to seek to the end of the file, get the position (wich will tell you its size), then seek back to the start.
The fastest approach though would be to use stat or fstat to get the file size information from the filesystem.
If you want number of digits thin you tave to do it char-by-char e.g:
while (isdigit(fgetc(file_decriptor))
count++;
Look up fgetc, getc and scanf in manpages, you don't seem to understand whats going on in your code.
The way C initializes values is not specified. Most of the time it's garbage. Your count variable it's not initialized, so it mostly have a huge value like 1243435, try int count = 0.