#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.
Related
I'll preface this with the standard: I am very new to C programming so please be gentle.
I'm writing a C program that should be able to take a file path/filename as a command line arg, failing that, it should accept user input. I have the argv[1] filename working, but I don't know how to get it to switch to stdin if the user doesn't add a file name as an arg. The input should be raw data, not a filename. here's my (very newbie) code. As a new programmer I may need some extrapolation of explanation and I apologize in advance for this.
int main(int argc, char* argv[]) {
#ifndef NDEBUG
printf("DBG: argc = %d\n", argc);
for (int i = 1; i < argc; ++i)
printf("DBG: argv[%d] = \"%s\"\n", i, argv[i]);
#endif
FILE* stream = fopen(argv[1], "r");
char ch = 0;
size_t cline = 0;
char filename[MAX_FILE_NAME];
filename[MAX_FILE_NAME - 1] = 0;
if (argc == 2) {
stream = fopen(argv[1], "r");
if (stream == NULL) {
printf("error, <%s> ", argv[1]);
perror(" ");
return EXIT_FAILURE;
}
}
else if (argc ==1)
printf("Enter a list of whitespace-separated real numbers terminated by EOF or \'end\'\n");
//continue with program using user-input numbers
Your code is overly complicated and wrong. You're doing things in the wrong order. You first need to check if an argument is there and try to open the file only in that case.
You want something like this:
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
FILE* input = stdin; // stdin is standard input
// so if no arguments are given we simply read
// from standard input (which is normally your keyboard)
if (argc == 2) {
input = fopen(argv[1], "r");
if (input == NULL) {
fprintf(stderr, "error, <%s> ", argv[1]);
perror(" ");
return EXIT_FAILURE;
}
}
else
printf("Enter a list of whitespace-separated real numbers terminated by EOF or \'end\'\n");
double number;
while (fscanf(input, "%lf", &number) == 1)
{
// do whatever needs to be done with number
printf("number = %f\n", number);
}
fclose(input);
}
I have an assignment to write a program that copies takes 2 arguments (filePaths) and copies the first file into the second.
As far as I can tell, I should I'm supposed to use fgets.
What I have seems to work, up until the end when I can't get detect the end of the file. According to everything I've read, it seems like fgets is supposed to stop when it hits the end of the file and return null or something, but if I let it this keeps reading the last line of the file.
Here's the code. I don't want answers (this is homework), I just want to understand what I'm doing, so I can get the answer myself:
#include <stdio.h>
#define BUFFER_SIZE 80
int readLineFromFile(FILE* file, char* buffer) {
if(! *fgets(buffer, BUFFER_SIZE, file)) {
return -1;
}
int length;
for(length=0; buffer[length] != '\0'; length++);
return length;
}
void writeLineToFile(FILE* file, char* buffer) {
fprintf(file, "%s", buffer);
}
int main(int argc, char **argv) {
if (argc != 3) {
printf("incorrect number of arguments, 2 text files expected, recieved %d\n", argc - 1);
return 0;
}
FILE* input = fopen(argv[1], "r");
FILE* output = fopen(argv[2], "w");
char buffer[BUFFER_SIZE];
int charsRead = readLineFromFile(input, buffer);
int i;
while(0 < charsRead) {
writeLineToFile(output, buffer);
charsRead = readLineFromFile(input, buffer);
printf("%d\n", i++);
}
fclose(input);
fclose(output);
return 0;
}
I think the problem is with the function dereferencing in if(! *fgets(buffer, BUFFER_SIZE, file)) {. I changed *fgets to fgets and it ran fine. See the correct code here. But for extra credit, figure out how to make this work with any filetype, not just plaintext.
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]
// ...
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.
Alrighty, so after a day and a bit of being on stackoverflow, I learned it's useful being on this site :) I ended up getting my program to work. I can get an unlimited amount of text files in on the command line and display them as well! So it looks like this:
CMD Console
c:\Users\Username\Desktop> wrapfile.exe hello.txt how.txt. are.txt you.txt random.txt
Hello How are you doing today? I hope you're doing quite well. This is just a test to see how much I can fit on the screen.
Now, I wana build on this program. How would I get this new found text to wrap around? Like, if you wanted to make it that, every 40 characters or so, the text jumps to the next line... how could we go about doing something like that?
Thanks again!
Here's the code I'm working with:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int l = 1;
while(l != argc)
{
FILE *fp; // declaring variable
fp = fopen(argv[l], "rb");
l++;
if (fp != NULL) // checks the return value from fopen
{
int i = 1;
do
{
i = fgetc(fp); // scans the file
printf("%c",i);
printf(" ");
}
while(i!=-1);
fclose(fp);
}
else
{
printf("Error.\n");
}
}
}
Okay, here we go...this looks a little different to yours, but this is ISO/ANSI C 1989 standard.
int main(int argc, char **argv)
{
FILE *fd = NULL;
char linebuf[40];
int arg = 1;
while (arg < argc) {
fd = fopen(argv[arg], "r");
if (NULL != fd) {
/* fgets(char *buf, size_t buflen, FILE *fd): returns NULL on error. */
while (NULL != fgets(linebuf, sizeof(linebuf), fd)) {
printf("%s\n", linebuf);
}
fclose(fd);
} else {
fprintf(stderr, "Cannot open \"%s\"\n", argv[arg]);
}
++arg;
}
}