Print in text instead of binary format in cat implementation - c

The implementation of the cat program is printing in binary format on the Ubuntu terminal. I am using the stdout macro (object of type FILE*).
#include <stdio.h>
main(int argc, char** argv)
{
FILE *fp;
void add(FILE*, FILE*);
if (argc==1)
add(stdin,stdout);
else
while(--argc>0)
{
if ((fp=fopen(*++argv,"r"))==NULL)
{
printf("cat:can't open %s\n",*argv);
return 1;
}
else
{
add(fp,stdout); // printing all the file content on the screen.
fclose(fp);
}
return(0);
}
}
void add(FILE*p,FILE*q)
{
int c;
while((c=fgetc(p))!=EOF)
{
fputc(c,q);
}
}
Now, how can I print in text format instead of binary format?

The error is in how you loop over the arguments. Stripping your code of the actual file processing and replacing it with a print statement (and also nicely indenting it), we get:
if (argc == 1)
printf("stdin\n");
else
while (--argv > 0) {
printf("'%s'\n", *++argv);
}
You have mistyped argc for argv in your code. That means you decrement the pointer to the first argument and then increment it again before processing the file. Effectively, you end up processing argv[0] over and over. That file is the program itself, which is binary and contains many non-printable characters.
You should chzange the loop to
while (--argc > 0) {
printf("'%s'\n", *++argv);
}
or use a pedestrian for loop:
for (int i = 1; i < argc; i++) {
printf("'%s'\n", argv[i]);
}

program has no any error only typo mistake argv instead argc rest all is good even than above suggested answer

Related

How to Display Content of Multiple FIles Given in command Line argument in C

So I am trying to print the content of files which are given as an argument and the problem i am facing is when multiple arguments are passed it display the content of first file only.
Like if i give Input as a.txt b.txt c.txt it displays the output of a.txt and ends
the code i have written so far is:
#include<stdio.h>
int main(int argc,char*argv[])
{
if(argc<3)
{
printf("Insufficent Arguments");
exit(0);
}
int i;
FILE *fp;
char c;
for(i=1;i<argc;i++)
{
fp=fopen(argv[i],"r");
if (fp == NULL )
{
fprintf( stderr, "could not open file named %s!\n",argv[i] );
return 2;
}
else
{
while (c != EOF)
{
printf ("%c", c);
c = fgetc(fp);
}
}
fclose( fp );
}
}
This code is after all possible modifications i have tried to resolve the problem
Please can anyone guide me what am i doing wrong?
After the first loop, you need to reset c. If you don't it keeps the last value from the previous file.
Also c needs to be int.
pseudo code
int main(int argc, char **argv) {
int c;
for (int i = 1; i < argc; i++) {
c = 0;
while (c != EOF) {
/* ... */
}
}
}
You may want to re-initialize your char 'c', that is used to check EOF.
After first iteration/file, it ends up with EOF and since this char is declared outside it retains its value across files. So for other file it will never go inside while loop.
option 1: Move your char c; declaration inside else
Or
option 2: re-initialize your c before while, c = fgetc(fp); (yes, you will have to restructure print)

Print out first line of input file char by char, but nothing comes to screen

So Im trying to print out the first line of a file thats being passed in lets say its a plain text file with a couple of words in the first line.
I open the file and pass it through a function that does some work on the file called process. This little bit of work if for debugging reason , because my ultimate goal is to read in the entire text file line my line and process each line and reverse the words in that line.
But im stuck here i run the program with a text file argument and i get nothing in return and i know my logic sounds right i think? I just want this to ultimately printout every character in that line. Then eventually put all those characters in a char array or char instream[500]
Can someone tell me what iam doing wrong?
#include <stdio.h>
#include <stdlib.h>
void process(FILE *infile);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
printf("argc = %d\n",argc);
for(i = 1 ; i <= argc; i++)
{
fp = fopen(argv[i], "r");
if(fp == NULL)
{
printf("The file: %s doesnt exist.\n", argv[i]);
}
else
{
printf("The file: %s does exist \n",argv[i]);
process(fp);
}
}
return 0;
}
void process(FILE *infile)
{
int k =0;
char iochar;
char instream[500];
while((iochar = getc(infile)) != '\n')
{
printf("Hi there %c", iochar ); // nothing prints out here why not??
//instream[k++] = iochar;
}
}

Debug Assertion Error in C

got some code here that won't compile correctly because it is saying that my pointer is already null when i am testing for a not null expression in my main function. here is the code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCODE 53
#define MAXMESSAGE 256
void getCode(char *codeIn, char *filename) {
FILE *codeFile;
/* Open the file with the code */
codeFile = fopen(filename, "r");
if (codeFile == NULL) {
printf("Error opening the code file - program terminated\n");
exit(1);
}
/* Read the first (and assumed only) line from the file */
fgets(codeIn, MAXCODE, codeFile);
/* Terminate the string with /0 */
codeIn[MAXCODE] = '\0';
/* Close the file */
fclose(codeFile);
return;
}
int getMessage(int *message, char *filename) {
FILE *messageFile;
int counter = 0;
/* Open the file with the message */
messageFile = fopen(filename, "r");
if (messageFile == NULL) {
printf("Error opening the message file - program terminated\n");
exit(1);
}
/* Read one number at a time from the file and store it */
while (!feof (messageFile))
{
fscanf (messageFile, "%d", (message+counter));
counter++;
}
/* Close the file */
fclose(messageFile);
return (counter);
}
void sortMessage(int *message, int size) {
int i, j, temp;
for (i=0; i<size-1; i++) {
for (j=i; j<size; j++) {
if (message[i]>message[j]) {
temp = message[i];
message[i] = message[j];
message[j] = temp;
}
}
}
return;
}
void decodeMessage(char *codeIn, int *message, int size) {
FILE *outputFile;
int i = 0;
/* Open the output file */
outputFile = fopen("csis.txt", "w");
if (outputFile == NULL) {
printf("Error opening the output file - program terminated\n");
exit(1);
}
for (i=0; i< size; i++) {
fprintf(outputFile, "%c", codeIn[message[i]%100]);
printf("%c", codeIn[message[i]%100]);
}
printf("\n");
/* Close the file */
fclose(outputFile);
return;
}
int main(int argc, char *argv[])
{
char code[MAXCODE];
int msg[MAXMESSAGE];
int msgSize;
if (argc != 3) {
printf("This program takes two arguments: the name of the file with the code, and the name of the file with the encoded message\n");
}
getCode(code, argv[1]);
msgSize = getMessage(msg, argv[2]);
sortMessage(msg, msgSize);
decodeMessage(code, msg, msgSize);
return;
}
So basically my code is using two files called codefile.txt and msgfile.txt to decode the secret message and write the decoded sequence to a new text file called csis.
As woolstar pointed out in the comments, you don't need to NUL terminate your codeIn array following fgets, because fgets will do that for you. In fact, this constitutes an overflow which we can best see by considering what happens when MAXCODE is 1: codeIn contains only one element: codeIn[0], and accessing codeIn[1] is an error.
Similarly, since MAXCODE is 53 and that's how many elements pointed to by codeIn, codeIn[message[i]%100] is suspicious because there's a potential for message[i]%100 to be an invalid index. While we're on this note, it might be wise to make message[i] an unsigned int so that it can't be negative. The format specifier (for printf and scanf) corresponding to unsigned int is %u.
while ( !feof(messageFile) ) is wrong because the EOF flag isn't set until an attempt is made at reading. Between attempting to read and your EOF test, however, you've incremented counter which means you've counted one too many items. Perhaps your loop should look like this:
while (fscanf(messageFile, "%d", (message+counter)) == 1)
{
counter++;
}
Note that this code assumes you've chosen to keep message[i] as an int. If you've chosen to use unsigned int instead, of course you'll want to use the %u format specifier.
You can probably see that feof is mostly superfluous... You can usually test for erroneous reads by checking the return value. Try to avoid feof in the future.
Your main function has a return type of int, yet at the end of it you have a return; statement which doesn't return an int value. Remove that. It's probably causing errors during compilation.
Presumably, when argv != 3 you want to return from main so you don't end up processing invalid arguments... Make sure you return an int value, e.g.
if (argc != 3) {
printf("This program takes two arguments: the name of the file with the code, and the name of the file with the encoded message\n");
return 0;
}

how to increment argv

int main(int argc,char *argv[])
{
int f1,flag,n;
if(argc<3)
{
printf("Correct format: ./a.out <fileName> <string>\n");
exit(-1);
}
f1=creat(argv[1],0666);
if(f1<0)
{
printf("Creatioon error\n");
exit(f1);
}
n=strlen(argv[2]);
printf("%d\n",n);
while(n-->0)
flag=write(f1,argv[2]++,1);
if(flag<0)
{
printf("Write error\n");
exit(flag);
}
close(f1);
return 0;
}
here in flag=write(f1,argv[2]++,1); why do we do argv[2]++ and why is the length of the text to be copied is 1??
The increment is because it's in a (stupid) loop:
while(n-->0)
flag=write(f1,argv[2]++,1);
but your code isn't indented so it's a bit harder to see.
argv[2] is a char * pointing at the string entered as the third word on the command-line, so incrementing it steps it to the next character in the string.
This is bad code; it should be write(fl, argv[2], n); to write it all at once. Of course, the return value must still be inspected and the write() maybe looped to try again or resume if there is a partial write.
The length is 1 because the 3rd argument of write is 1.
You probably want this:
/* write second command line argument to the file */
flag=write(f1, argv[2], strlen(argv[2]);

Why am I segfaulting?

I'm very new to C, I am attempting to read the contents of one file character by character and output them to the stream. But even with my fopen() command commented out I receive segfault (core dumped).
I must run a command: ./a.out < testWords.in > myOut.txt to execute my file properly.
Here is what I have so far:
#include <stdio.h>
void main(char *fileName[])
{
printf("filename is %s.\n",fileName[0]);
//Get file based on a string inputed
FILE *fp=fopen(fileName[0],"r"); //Fetches our file as read only
char ch;
int lineCount = 0;
int wordCount = 0;
int charCount = 0;
//Failed to find/open file. NULL character.
if (fp == 0) printf("Woops! Couldn't open file!\n");
//While not at end of file, grab next char.
else while( (ch=fgetc(fp)) != EOF)
{
if (ch == '\n') //on newline
{
//Prints (charCount,wordCount)\n lineCount:
printf("(%d,%d)%c%d:",charCount,wordCount,ch,lineCount);
charCount = 0;
lineCount += 1;
}
else printf("%c",ch); //mirrors char.
}
fclose(fp); //Closes file (gotta be tidy!)
}
You can't just invent a way to call main. You need to use one of the standard ways, like this:
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr, "Missing filename\n");
return -1;
}
FILE *fp = fopen(argv[1], "r");
// ...
}
And note that argv[0] contains the program name (if available; if not it contains an empty string).
Your program segfaulted because you received the int argc argument into your char *filename[] parameter. If you ran the program with a single command line parameter, the value passed in as the first argument would have been 2, which is not a valid pointer value. The expression filename[0] dereferences that address and causes a segfault.
Any time you get a segfault in C, you should smell a bad pointer or address in an argument list. In this particular case., the signature of main is always int main(int argc, char** argv). Yours isn't.
What you want is
int main(int argc, char ** argv) {
...
FILE * fp = fopen(argv[1]); // Quiz: why argv[1]? What's argv[0]?
You're getting away with it in the compiler because, basically, luck.
I also notice in your example call, there's actually no argument in the argument list, because you're using redirection.
Use:
int main(int argc, char* argv[])
And use argv[1] as fileName.
Main function must receive always that two parameters.

Resources