fread not writing to ptr - c

I'm trying to read the contents of a file with fread, however the contents are not being written to the ptr. I've verified with the ftell() function that the position in the stream is changing, however no content is written to the ptr.
I've implemented the same functionality in another code, the only difference being that in that case it was a struct instead of char *, I can't figure out based on the documentation why this is the case.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 2)
{
fprintf(stderr, "Usage: recover infile\n");
return 1;
}
char *infile = argv[1];
// open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
fprintf(stderr, "Could not open %s.\n", infile);
return 2;
}
char *block;
block = malloc(sizeof(char)*64);
fread(block, 1, 64, inptr);
printf(" es %s \n", block);
int position = ftell(inptr);
printf("position %d \n", position);
free(block);
fclose(inptr);
}
The malloc is currently a placeholder btw.
Any explanations as to why the data on the file isn't being written to block?

In general, if you want to understand better what is the output of a printf, you could write:
printf("Test: <%s> - (len=%lu)\n", block, strlen(block));

Related

Trying to read first line of file using fgets

I'm trying to write a program that will read the first line of a txt file and output it. I can't get the fgets to display in my fprintf statement when running the program.
#include "example.h"
// function: main
int main(int argc, const char** argv) {
//declare filepointer
FILE *fp;
//declare variables
char c[10];
long size;
//open file
fp = fopen(argv[1], "r");
//first output read dimension of vector
fgets (c, 10, fp);
fprintf(stdout, "the dimension of the vector is %s\n", c);
fclose(fp);
return 0;
}
The text file has the following contents:
4
45.0
62.0
55.6
8.2
But my output is just reading as:
the dimension of the vector is
You always need to be careful of what the user is going to enter as input in the program. To do this, as mentioned in the comment, we should always check if the fopen(), fgets(), and the arguments are correctly passed before taking them into use.
Let's try the following code:
#include <stdio.h>
#define EXIT_FAILURE 1
#define MAX_LEN 16
int main(int argc, char *argv[]) {
FILE *fp = NULL;
char c[MAX_LEN];
if (argc != 2) {
fprintf(stdout, "Usage: %s <file>\n", argv[0]);
return EXIT_FAILURE;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
perror(argv[1]);
fclose(fp); // Cleanup
return EXIT_FAILURE;
}
if (fgets(c, sizeof(c), fp) == NULL) {
fprintf(stderr, "File read error.\n");
fclose(fp); // Cleanup
return EXIT_FAILURE;
}
fclose(fp);
fprintf(stdout, "The dimension of the vector is %s\n", c);
return 0;
}
In this case, I've got those same values as yours in the data.txt file.
The program outputs:
rohanbari#genesis:~/stack$ ./a.out data.txt
The dimension of the vector is 4

Why does this fread segfault

I have tried many things to fix this segfault issue, I'm not sure whats happening wrong because from my understanding, the fread line should not segfault
// ensure proper usage
if (argc != 2)
{
fprintf(stderr, "Usage: ./recover file");
return 1;
}
char* recover = argv[1];
// open input file
FILE * raw_file = fopen(recover, "r");
if (raw_file == NULL)
{
fprintf(stderr, "Could not open %s.\n", recover);
return 2;
}
//somehow read the file
int counter = 1;
char file[2];
sprintf(file,"%03i.jpg",counter);
int buffer[512];
//read file and put into buffer
int*bf = malloc(sizeof(int));
fread(bf, sizeof(int), 1, raw_file);
you smashed you stack in this block prior to your fread
char file[2];
sprintf(file,"%03i.jpg",counter);
file is to small to hold the number of characters you are formatting into it.

Why the hyphen(-) is not printed?

#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[])
{
FILE* fp = fopen(argv[1],"r");
char* ptr;
int size;
while(1){
int scanfinteger = fscanf(fp,"%d",&size);
ptr = (char*)malloc((size+1)*sizeof(char));
if(scanfinteger != 1){
int result = fscanf(fp,"%s",ptr);
printf("ptr:[%s]\n",ptr);
if(result == EOF)
break;
}
}
return 0;
}
input_file(argv[1]) contains this
10 This
10 is
10 buffers
10 -
10 hi
10 -hello
my program's output
ptr: [This]
ptr: [is]
ptr: [buffers]
ptr: [10]
ptr: [hi]
ptr: [hello]
I can't understand why the hyphen gets consumed. Has someone had seen this issue?
Thank you!
If I may suggest a different solution, I would suggest you read lines and then parse the lines.
Perhaps something like this:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc, char* argv[])
{
// First make sure you have enough arguments
if (argc < 2)
{
printf("Need an argument!\n");
return 1;
}
// Open the file, and make sure we succeeded
FILE *fp = fopen(argv[1], "r");
if (fp == NULL)
{
printf("Failed to open the file %s: %s\n", argv[1], strerror(errno));
return 1;
}
// Now read the file, one line at a time
char line[100];
while (fgets(line, sizeof line, fp) != NULL)
{
// Now we have a line, attempt to parse it
int value;
char string[100];
if (sscanf(line, "%d %99s", &value, string) != 2)
{
printf("Failed to parse the current line\n");
break; // Break out of the loop
}
printf("Read value %d, string '%s'\n", value, string);
}
// All done, or we had an error (should probably check that)
// Anyway, close the file and end the program
fclose(fp);
}
The problem with your current code (which doesn't seem to be the actual code you run) is that you only read the string if the reading of the number fails.
What the problem is with your actual code, that produces that output, I don't know. But somehow it comes out of sync. This can be seen in that you for one line read the number as the string.

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]
// ...

Why wont the program read from the 2 argument file?

So the assignment is to implement a substring search program using an input file to be searched from and an input to be searched. I created the following code:
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *fp;
fp = fopen(argv[1],"r");
if (fp == NULL)
{
printf("Error");
return 0;
}
char* tmpp[100];
int count = 0;
char* nexts = argv[2];
char* tmp = fgets(tmpp,100,fp);
while(tmp = strstr(tmp,nexts))
{
count++;
tmp++;
}
printf("%d\n\n",count);
fclose(fp);
return 0;
}
The program compiles but when i go to implement it in the ubuntu terminal as:
echo "aabb" >beta
./a.out beta a
1
Why isnt the program using the first argument (argv[1]) as beta and the second argument (argv[2]) as a correctly?
You should open a file and then read bytes from that file into temporary buffer:
FILE *file = fopen("file", "r");
while (1) {
char buffer[BUFSIZ+1];
size_t nread = fread(buffer, 1, sizeof(buffer)-1, file);
if (nread == 0) break; // read error or EOF
buffer[nread] = 0;
// chunk with BUFSIZ amount of bytes is available via buffer (and is zero-terminated)
}
If you want to search for string/pattern in a file, be aware that looked pattern in file may cross your chunk-size boundary, for example: you look for "hello", and BUFSIZ is 512. File contains "hello" at byte 510. Obviously, if you read by 512, you will get the first chunk ending with "he", and the second chunk starting with "llo". Probability of this situation is nonzero for all chunk sizes (except SIZE_MAX, but that buffer size is impossible by other reasons). Dealing with borders may be very complicated.
Close...but this is closer:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc != 3)
{
fprintf(stderr, "Usage: %s file pattern\n", argv[0]);
return 1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL)
{
fprintf(stderr, "Error: failed to open file %s for reading\n", argv[1]);
return 1;
}
char tmpp[1000];
int count = 0;
char* nexts = argv[2];
while (fgets(tmpp, sizeof(tmpp), fp) != 0)
{
char *tmp = tmpp;
while ((tmp = strstr(tmp, nexts)) != 0)
{
count++;
tmp++;
}
}
printf("%d\n", count);
fclose(fp);
return 0;
}
The main difference is that this loops reading multiple lines from the input file. Yours would only work on files with a single line of input.

Resources