Cant scan file in C - c

I am cant seem to get my simple script to read the file. All i am trying to do is read letters into an array. I just get random characters and it is driving me crazy. I have the file in the Debug folder, what else can go wrong? I am 100 percent sure everything is correct.
Here is my code:
FILE * ifp;
ifp = fopen("letters.txt", "r");
int i;
int bound = 20;
char data[20];
for(i =0; i<bound; i++){
fscanf(ifp, "%s", &data[1]);
if (ifp == NULL){
return;
}
printf("Data %d = %c\n", i, data[i]);
}

The following code
1) checks for errors
2) compiles cleanly
3) works on a test.txt file I produced.
#include <stdio.h>
#include <stdlib.h>
#define bound (20)
int main( void )
{
FILE * ifp;
if( NULL == (ifp = fopen("letters.txt", "r") ) )
{ // then, fopen failed
perror( "fopen for letters.txt failed");
exit( EXIT_FAILURE );
}
// implied else, fopen successful
int i;
char data[bound];
for(i =0; i<bound; i++)
{
if( 1 != fscanf(ifp, "%c", &data[i]) )
{ // then fscanf failed
perror( "fscanf failed" );
exit( EXIT_FAILURE );
}
// implied else, fscanf successful
printf("Data %d = %c\n", i, data[i]);
}
return(0);
} // end function: main

Hmm could it be because
&data[1]
should be just
data
or the equivalent
&data[0]
which is likely what you intended.
?
Only other reason I can think of is, the line you are reading is greater than 20 characters and its overflowing the data array.
Have a look at this example: http://www.tutorialspoint.com/c_standard_library/c_function_fscanf.htm

Here's an example:
#include <stdio.h>
#define MAX_LINES 10
#define MAX_LINE 80
#define FILE_NAME "lines.txt"
int
main (int argc, char *argv[])
{
char lines[MAX_LINES][MAX_LINE];
FILE *fp;
int i = 0;
if (!(fp = fopen(FILE_NAME, "r"))) {
perror ("file open error");
return 1;
}
while (i < MAX_LINES) {
if (fgets (lines[i], MAX_LINE, fp)) {
printf ("Line[%d]=%s", i, lines[i]);
i++;
} else {
printf ("End of file: closing %s\n", FILE_NAME);
break;
}
}
fclose (fp);
return 0;
}
Sample output:
$ gcc -o x1 -Wall -pedantic -g x1.c
$ ./x1
Line[0]=Come and listen to my story
Line[1]='Bout a man named Jed
Line[2]=Poor mountaineer,barely kept his fam'ly fed
End of file: closing lines.txt
Note:
We're reading a line at a time
We're reading each line into an array
We define the #/elements in the array (MAX_LINES) and the maximum size of each string (MAX_LINE) ahead of time
We check for "file open error" (and return "non-zero" accordingly)
We use "fgets()" to safely read a line (without risking a buffer overrun).
If you wanted to read a character at a time, the program could be as simple as:
char string[MAX_LINE], *c;
...
if (!(fp = fopen(FILE_NAME, "r"))) {
perror ("file open error");
return 1;
}
...
c = string;
while ((*c = fgetc (fp)) != EOF)
c++;
One problem with the second example is that it doesn't check for string length >> MAX_LINE. But hopefully it helps give you some ideas...

Related

Rename a file and save it as a another one

I'm trying to get a filename that exists at the beginning. After that I want to add _blabla.txt to the filename and create the another one.
Here the example. --> example.txt (what I get)
Here the what I want. --> example_blabla.txt (what I want to create)
I tried to use sprintf(filename, "%s%s", argv[1], "_blabla.txt") but the created file's name is example.txt_blabla.txt.
How can I remove extension of first filename from the filename that I created ?
Here is my code:
FILE *fp;
FILE *fp2;
char filename[300];
if (argc != 2 || argv[1] == NULL) {
printf(" You did not enter a file name! \n");
exit(-1);
}
sprintf(filename, "%s%s", argv[1], "_blabla.txt");
fp = fopen(argv[1], "r");
fp2 = fopen(filename, "w");
return 0;
Here are some suggestions:
to locate the last '.' in the string, you can use the function strrchr() from <string.h>.
to avoid undefined behavior on overlong strings, use snprintf instead of sprintf.
to copy a portion of a string with snprintf, use %.*s with an int argument before the string pointer.
Here is a modified version:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
FILE *fp;
FILE *fp2;
char filename[300];
char *p;
int pos;
if (argc != 2) {
printf(" You did not enter a file name!\n");
return -1;
}
p = strrchr(argv[1], '.');
if (p != NULL)
pos = p - argv[1];
else
pos = strlen(argv[1]);
// Using the %.*s precision field to limit the number of characters
// copied from `argv[1]`
snprintf(filename, sizeof filename, "%.*s_blabla.txt", pos, argv[1]);
fp = fopen(argv[1], "r");
if (fp == NULL)
return 1;
fp2 = fopen(filename, "w");
if (fp2 == NULL)
return 1;
/* copy the file */
fclose(fp);
fclose(fp2);
return 0;
}
Append the following statements before and after your sprintf() call as follows:
int i;
char *pChar = NULL;
for (i = strlen(argv[1]) - 1; i >= 0: i--) {
if (argv[1][i] == '.') {
pChar = &argv[1][i];
*pChar = '\0';
break;
}
}
sprintf(filename,"%s%s",argv[1],"_blabla.txt");
if (pChar != NULL)
*pChar = '.';
the following proposed code:
demonstrates a method to extract the root name from a filename then append a set of characters.
demonstrates how to inform the user when the command line parameter is missing.
does not perform a stat() to assure the source file actually exists, That is left to the OP to include.
properly checks for I/O errors
documents why each header file is included
suggest getting the length of the argv[1] parameter, add the length of blabla.txt, add 1, then use the VLA feature of C to appropriately size the array filename[]. Note: strlen() works well for obtaining the length of a NUL terminated char array
And now, the proposed code:
#include <stdio.h> // fopen(), fclose(), perror(), fprintf(), FILE
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <string.h> // strrchr(), strcat()
int main( int argc, char (argv[] )
{
FILE *fp;
FILE *fp2;
char filename[300];
if (argc != 2 )
{
fprintf( stderr, "USAGE: %s fileName\n", argv[0] );
exit( EXIT_FAILURE );
}
strcpy(filename, argv[1] );
char *ptr = strrchr( filename, '.' );
if( ptr )
{
*ptr = '\0';
}
strcat( filename, "_blabla.txt");
fp = fopen(argv[1], "r");
if( ! fp )
{
perror( "fopen for input file failed" );
exit( EXIT_FAILURE );
}
fp2 = fopen(filename, "w");
if( ! fp2 )
{
perror( "fopen for output file failed" );
fclose( fp1 );
exit( EXIT_FAILURE );
}
return 0;
}

C program to print given number of lines from beginning of text file. File name and number of lines from command line argument

I'm writing a program said in this post title. I take reference at this webpage.
https://www.includehelp.com/c-programs/c-program-to-print-given-number-of-lines-of-a-file-like-head-command-in-linux.aspx
Here are the codes from that webpage.
#include <stdio.h>
int main(int argc, char * argv[])
{
FILE *fp; // file pointer
char *line = NULL;
int len = 0;
int cnt = 0;
if( argc < 3)
{
printf("Insufficient Arguments!!!\n");
printf("Please use \"program-name file-name N\" format.\n");
return -1;
}
// open file
fp = fopen(argv[1],"r");
// checking for file is exist or not
if( fp == NULL )
{
printf("\n%s file can not be opened !!!\n",argv[1]);
return 1;
}
// read lines from file one by one
while (getline(&line, &len, fp) != -1)
{
cnt++;
if ( cnt > atoi(argv[2]) )
break;
printf("%s",line); fflush(stdout);
}
// close file
fclose(fp);
return 0;
}
My problem is the getline function. Since I'm not using Linux that function's giving error in my compiler. I tried to change it to fgets function. This is my revised codes.
I got two errors in the line ' while (fgets(&line, bufferLength, fp) != -1)'.
Error: passing argument 1 of 'fgets' from incompatible pointer type.
Error: comparison between pointer and integer.
My question is - how can I modify the program using fgets? Many thanks to anyone who can work this out.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp; // file pointer
char *line = NULL;
int bufferLength = 255;
int cnt = 0;
if( argc < 3)
{
printf("Insufficient Arguments!!!\n");
printf("Please use \"program-name file-name N\" format.\n");
return -1;
}
// open file
fp = fopen(argv[1],"r");
// checking for file is exist or not
if( fp == NULL )
{
printf("\n%s file can not be opened !!!\n",argv[1]);
return 1;
}
// read lines from file one by one
while (fgets(&line, bufferLength, fp) != -1)
{
cnt++;
if ( cnt > atoi(argv[2]) )
break;
printf("%s",line);
fflush(stdout);
}
// close file
fclose(fp);
return 0;
}
Your program should compile and run correctly follows:
//c program to print given number of lines from beginning of a file
//file name and number of lines must be supply as command line argument
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
FILE* fp; // file pointer
char* line = malloc(255);
int bufferLength = 255;
int cnt = 0;
if( argc < 3)
{
printf("Insufficient Arguments!!!\n");
printf("Please use \"program-name file-name N\" format.\n");
return -1;
}
// open file
fp = fopen(argv[1],"r");
// checking for file is exist or not
if( fp == NULL )
{
printf("\n%s file can not be opened !!!\n",argv[1]);
return 1;
}
// read lines from file one by one
while (fgets(line,bufferLength, fp))
{
cnt++;
if ( cnt > atoi(argv[2]) )
break;
printf("%s",line);
fflush(stdout);
}
// close file
fclose(fp);
free(line);
return 0;
}
we have two main problems, first
char * line = NULL;
line is a line of characters, a string if you want to call it that, so we must reserve enough memory to accommodate a complete line, and we do this with the malloc function, as seen in the program, the other problem we have with fgets, this function returns a pointer therefore we cannot compare the value returned by fgets with an integer, the declaration
while (fgets (line, bufferLength, fp))
is equivalent to running the loop while fgets is other than NULL. Finally we must use line instead of &line, the latter asks for the address of the line pointer, and not the address it points to.
There's no need to keep track of more than a single character. Reading full lines is overkill. Just do:
#include <stdio.h>
#include <stdlib.h>
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = fopen(path, mode);
if( fp == NULL ) {
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}
int
main(int argc, char **argv)
{
int count = argc > 1 ? strtol(argv[1], NULL, 10) : 1;
FILE *in = argc > 2 ? xfopen(argv[2], "r") : stdin;
int line = 0;
int c;
while( line < count && ( c = fgetc(in)) != EOF ) {
putchar(c);
if( c == '\n' ) {
line += 1;
}
}
}
Note that I've reversed the order of the arguments, so that stdin is read if only a count is given.

I want to concatenate n files but the concatenation is not in correct order?

I am trying to write a C program to concatenate N files which I should read them from the keyboard and then take all of their concent starting from FILE1 to n and put them on a NEWFILE, my program concatinates all of the N files but the order is not from 1 to n. For example:
I input N=3 and I put three files:
text1.txt (inside the file I have "We cannot")
text2.txt ("live")
text3.txt ("without water.")
and then save the concatination on a finalresult.txt
Now my finalresult.txt should be:
We cannot
live
without water.
But my result is:
withoutwater. We cannot live
Here is my full program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int number;
scanf("%d", &number);
int i;
char a[number][50];
char help[50];
for(i=0; i<number; i++)
{
scanf("%s", help);
strcpy(a[i], help);
}
printf("Concating the content of %d files ...\n", number);
FILE * filer, * filew;
int numr,numw;
char buffer[64];
for(i=0; i<number; i++)
{
filer = fopen(a[i], "rt");
if(filer == NULL)
{
fprintf(stderr, "open read file error.\n");
exit(1);
}
filew = fopen("finalresult.txt","a+t");
if(filew==NULL) {
fprintf(stderr,"open write file error.\n");
exit(1);
}
while(feof(filer)==0) {
numr=fread(buffer,1,100,filer);
if(numr!=100) {
if(ferror(filer)) {
fprintf(stderr,"read file error.\n");
exit(1);
}
}
numw=fwrite(buffer,1,numr,filew);
if(numw!=numr) {
fprintf(stderr,"write file error.\n");
exit(1);
}
}
}
fclose(filer);
fclose(filew);
return 0;
}
You can rewrite this
char a[number][50];
char help[50];
for(i=0; i<number; i++)
{
scanf("%s", help);
strcpy(a[i], help);
}
as
char a[number][50];
for(i=0; i < number; ++i)
scanf("%s", a[i]);
you don't need another intermediate buffer. Also bear in mind, that "%s"
matches only non-empty characters, if your filename has an empty character,
scanf won't read the whole input and leave behind extra characters in the input
buffer, thus messing with the next scanf call. Here it would be better to use
fgets.
char a[number][50];
for(i = 0; i < number; ++i)
{
if(fgets(a[i], sizeof a[i], stdin) == NULL)
{
fprintf(stderr, "Could not read the filename\n");
exit(1);
}
a[i][strcspn(a[i], "\n")] = 0; // removing newline
}
I haven't seen the mode 't' for fopen, is that a an extension of the modes
for Windows?
A problem with your code is that you are calling
filew = fopen("finalresult.txt","a+t");
inside the loop but you never close it inside the loop. FILE* file is buffered,
that means when you use fprintf(file,...) or fwrite(..., file)
the content gets buffered and the content is physically written in the file at a
later point, for example when the buffer is full or you use fflush(filew). So
when you fopen the same file before doing a fflush or fclose, the old
buffered content remains in the buffer and is written at a much later point (in
your case when the program exits), thus overwriting your new content. Your new content
will have the same fate. At the end you end up with a mess because the content
gets overwritten at the end of the program. That's why you see "garbage" in the
file.
So, you have to do fclose before doing fopen with the same filename, or
better you should do the fopen before the loop.
Also this check is incorrect:
if(numr!=100) {
if(ferror(filer)) {
fprintf(stderr,"read file error.\n");
exit(1);
}
}
This would only be correct, if the file size is a multiple of 100. If it's not,
the last block will have less than 100 bytes and you would end your program,
even though the fread had no errors.
So I'd rewrite your program like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(void)
{
size_t num_of_files;
printf("Enter the number of files: ");
fflush(stdout);
if(scanf("%zu", &num_of_files) != 1)
{
fprintf(stderr, "Could not read the number of files\n");
exit(1);
}
int c;
// clearing the input buffer
while((c = getchar()) != '\n' && c != EOF);
char fnames[num_of_files][50];
for(size_t i = 0; i < num_of_files; ++i)
{
printf("Enter the filename %zu: ", i+1);
fflush(stdout);
if(fgets(fnames[i], sizeof fnames[i], stdin) == NULL)
{
fprintf(stderr, "Could not read the filename\n");
exit(1);
}
fnames[i][strcspn(fnames[i], "\n")] = 0; // removing newline
}
FILE *filew = fopen("finalresult.txt", "wt");
if(filew == NULL)
{
fprintf(stderr, "Could not open file finalresult.txt for writing: %s\n",
strerror(errno));
exit(1);
}
for(size_t i = 0; i < num_of_files; ++i)
{
FILE *filer = fopen(fnames[i], "rt");
if(filer == NULL)
{
fprintf(stderr, "could not open %s for reading, skipping: %s\n",
fnames[i], strerror(errno));
continue;
}
char buffer[100];
size_t len;
while((len = fread(buffer, 1, sizeof buffer, filer)) != 0)
{
if(fwrite(buffer, 1, len, filew) != len)
{
fprintf(stderr, "Error writing finalresult.txt\n");
fclose(filer);
fclose(filew);
exit(1);
}
}
if(!feof(filer))
fprintf(stderr, "file %s could not be read completely\n", fnames[i]);
fclose(filer);
}
fclose(filew);
return 0;
}

how to enter a function to a file in c

I have this function in a code that im trying to enter to an I/O file and I cannot seem to do it.
void show_list(int whyeven[stuff], char *hatred[stuff])
{
for (int g = 0; g < stuff - 1; g++)
{
if (whyeven[g] < 10 || whyeven[g] == 0)
{
printf("%s - %d (*) you should buy more of this stuff\n\n",hatred[g], whyeven[g]);
}
else if (whyeven[g] > 10)
{
printf("%s - %d\n\n", hatred[g], whyeven[g]);
}
}
}
int main()
{
show_list(moarstuff, items);
return 0;
}
printf() prints to stdout. You need to fopen() that file and then use fprintf() with the returned from fopen() FILE* pointer as the first argument.
/* Open the file for writing */
FILE* fp = fopen("filename.txt", "w");
/* Check for errors */
if (fp == NULL)
{
/* Notify the user of the respective error and exit */
fprintf(stderr, "%s\n", strerror(errno));
exit(1);
}
/* Write to the file */
fprintf(fp, "Hello!\n");
/* Close the file */
fclose(fp);
Note: Your question was quite unclear and this answer is based on what I could understand out of it.

Reading line by line from a file in C

What I am trying to do is print out the contents of a file line by line. I run the program in terminal by doing: ./test testText.txt. When I do this, random characters are printed out but not what is in the file. The text file is located in the same folder as the makefile. What's wrong?
#include <stdio.h>
FILE *fp;
int main(int argc, char *argv[])
{
char line[15];
fp = fopen(*argv, "r");
while((fgets(line, 15, fp)) != NULL)
{
printf(line);
printf("\n");
}
}
When I do this, random characters are printed out but not what is in the file
These characters are not random, and in fact they are coming from a file. It's not the file that you are trying to read, though - it's the executable file which you are running.
*argv represents the name of the executable; add this line to see what's in *argv:
printf("%s\n", *argv);
The actual command line arguments start at argv[1], so you need
fp = fopen(argv[1], "r");
The first argument passed on the command line is at argv[1], while *argv refers to argv[0]. argv[0] contains the filename of the executable - you are printing out the content of the executable.
The following code prints out the entire argv[] array, then reads your file and prints it.
#include <stdio.h>
int main( int argc, char *argv[] )
{
for( int i = 0; i < argc; i++ )
{
printf( "argv[%d] : %s\n", i, argv[i] ) ;
}
if( argc >= 2 )
{
FILE* fp = fopen( argv[1], "r" ) ;
if( fp != NULL )
{
char line[15];
while( fgets( line, sizeof(line), fp ) != NULL )
{
printf( "%s", line ) ;
}
}
}
return 0 ;
}
Note that fgets() will read an entire line including the , so there is no need to print '\n', especially because with only 15 characters, your line buffer may well not contain an entire line. Note also the tighter localisation of variables - your code needlessly made fp global.
Other refinements are the safe use of the array size rather than literal 15, and the use of a literal constant string for the format specifier. You should avoid passing a variable string for the printf() format string - if your input itself contains format specifiers, printf() will try to read data from arguments that do not exist with undefined results.
Q: What's wrong?
A humble critique:
#include <stdio.h>
FILE *fp; // Perhaps this should be declared inside main?
int main(int argc, char *argv[])
{
char line[15]; // Are the file lines all 14 characters or less? (seems small)
fp = fopen(*argv, "r"); // Opening the binary executable file (argv[0])? Intereting.
// Should check here to ensure that fopen() succeeded.
while((fgets(line, 15, fp)) != NULL)
OK... well, remember that this isn't a text file.. it's an executable (due to *argv). This will read some wacky (but not random) characters from the executable.
{
printf(line); // Bad practice. Should be: printf("%s", line);
Ok... now print the wacky characters?
printf("\n"); // Redundant. The '\n' characters will be supplied in 'line'.
}
// fclose() call missing.
// Integer return value for main() is missing.
}
Here is (perhaps) what was actually intended:
#include <stdio.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int rCode = 0;
FILE *fp = NULL;
char line[255+1];
if(argc != 2)
{
printf("Usage: %s {filepath}\n", *argv);
goto CLEANUP;
}
errno=0;
fp = fopen(argv[1], "r");
if(NULL == fp)
{
rCode=errno;
fprintf(stderr, "fopen() failed. errno:%d\n", rCode);
goto CLEANUP;
}
while(fgets(line, sizeof(line), fp)) /* --As per 'chux' comment */
printf("%s", line);
CLEANUP:
if(fp)
fclose(fp);
return(rCode);
}
Or, if the intent is truly to print the content of the executable, perhaps this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int rCode = 0;
FILE *fp = NULL;
off_t offset = 0;
errno=0;
fp = fopen(*argv, "r");
if(NULL == fp)
{
rCode=errno;
fprintf(stderr, "fopen() failed. errno:%d\n", rCode);
goto CLEANUP;
}
for(;;)
{
char line[16];
size_t bytesRead;
int index;
char ascii[16+1];
memset(ascii, 0, sizeof(ascii));
bytesRead = fread(line, 1, sizeof(line), fp);
if(0==bytesRead)
break;
printf(" %08zX | ", offset);
for(index=0; index < bytesRead; ++index)
{
printf("%02hhX%c", line[index], 7==index ? '-' : ' ');
ascii[index] = isprint(line[index]) ? line[index] : '.';
}
printf("%*s %s\n", (16 -index) * 3, "", ascii);
offset += bytesRead;
}
if(errno)
{
rCode=errno;
fprintf(stderr, "fgets() failed. errno:%d\n", errno);
}
CLEANUP:
if(fp)
fclose(fp);
return(rCode);
}
your file name found at index 1 of argv.
if (argc <= 1) {
printf("no file was given\n");
exit(-1);
}
// open file from argv[1]
// ...

Resources