Printing out an error message in terminal - c

I am working on a program that determines the mode of a set of values for example (3 4 2 3 3) should print out "3". The catch is the program must receive the option of the mathematical function to execute and its arguments as parameters in the main function so no user input. Everything must be inserted in the command line and check by using pointers. My program works except for example say the user enters (mode) but doesn't enter in any values after. This should then print a message that just says "ERROR" and the program ends. However it does not instead it prints
Johns-MacBook-Pro-2:AdvanceCalc jvdamore$ ./a.out mode
Segmentation fault: 11
when it should print
Johns-MacBook-Pro-2:AdvanceCalc jvdamore$ ./a.out mode ERROR
below is my code. So my question is does my if statement with strcmp(p[2], "") == 0 work in order to produce the desired error message? or am I doing something wrong?
int main(int n, char **p)
{
int i, x, A[100];
if (strcmp(p[1], "mode")==0){
if (strcmp(p[2], "") == 0){
printf("ERROR");
return -1;
}
for(i=2;i<n;i++){
if (sscanf(p[i], "%d", &x) != 1) {
printf("ERROR");
return -1;
}
if (x<1 || x>30){
printf("ERROR");
return-2;
}
A[i-2]= x;
}
find_mode(A, n-2);
}

Rather than comparing a string to "" with strcmp, you need to see if it is NULL. strcmp( NULL, "" ) does not work very well, and you should instead do:
if( p[2] == NULL )
(well, really, you should rename the varaible argv, and there are several other issues, but this is the main problem. Make sure you have checked that p[1] is not NULL before you reference p[2])

Related

Understand C exit() and stderr message behavior [duplicate]

This question already has answers here:
Why does printf not flush after the call unless a newline is in the format string?
(10 answers)
Closed 5 years ago.
I couldn't understand why the following behavior happens in my code
First lets check if there exists number that dividable by 5
int count = 1;
while (count < 10) {
if (count%5 == 0) {
fprintf(stderr, FIND);
exit(1);
} else {
printf("Not Yet");
count += 1;
}
Normally, I'm expecting that it will print "not yet" four times before it print FIND
however, it actually print FIND immediately even first four number doesn't go to the if statement. There is no output of "Not Yet". The output is simply
FIND
Anyway, I try to debug by adding one more line within the if statement.
int count = 1;
while (count < 10) {
if (count%5 == 0) {
printf("%d\n", count);
fprintf(stderr, INVALID_LINE);
exit(1);
} else {
printf("Not Yet");
count += 1;
}
}
The output becomes
Not YetNot YetNot YetNot Yet5
FIND
I couldn't understand
First code, why the program execute if-statement even if the condition doesn't satisfied.
Second code, when one print line is added, the code actually behave what I've expected
stderr is unbuffered. Anything you write to it goes out immediately. stdout, which printf writes to, is line buffered-- it only goes out when a new line character is encountered.

basic CLI program in C

Okay so overall im trying to complete a basic CLI C program which will complete functions such as clear, quit, cd, ls, help (bring up the unix man) etc.. i altered my code and so far i have this, im getting segmination error when trying to execute the cd command part of the program, (im very new to c btw);
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
int main (int argc, char *argv[])
{
char input[] = " ";
char *argument;
while(strcmp(input, "quit")!= 0)
{
printf("$");
scanf ("%s", input);
if(strcmp(input,"clear") == 0)
{
printf("\e[1;1H\e[2J");
}
else if(strcmp(argv[1],"cd") == 0)
{
if(chdir(argv[2]) == -1)
{
printf("\n directory does not exists");
}
}
else if(strcmp(input, "echo") == 0)
{
char str[50];
scanf("%[^\n]+", str);
printf(" %s", str);
}
}
}
input is declared as a ' ' (space) character. It will never match 'cd'.
This is probably more along the lines of what you want to achieve, where the first parameter is the command (cd), and the second will be the directory:
int main (int argc, char *argv[])
{
char *argument;
if(strcmp(argv[1],"cd") == 0)
{
if(chdir(argv[2]) == -1)
{
printf("\n directory does not exists");
}
}
Edit Also please note that there is no need for the else satement. If chdir does not return an error, it will change the directory, thus no need to call it again in an else.
Additionally, another tip for using system calls in general, it would be of great help if you print the error number returned by the system upon a failure in system call. This will make things easier when things start going wrong. To do this simply include <errno.h>' and modify the printf to printerrno` which gives specific details about the error:
printf("Chdir error: %d", errno);
For instance chdir() does not only return an error when the directory does not exist, but also for example if you do not have permissions to view the contents of the directory. See the man page for a list of possible errors.
To implement your own shell, you need to take input directly from stdin, not from command-line arguments (argv) from another shell. The basic pattern is like this:
Read input
Execute command
Print results
Loop back to step 1

Checking for command line arguments in C

I wrote this code to take input from the command line, and depending on the input, will perform a set of actions, or if the input is incorrect, throws an error. However, I also need to check if no arguments are supplied, which I try to account for in my else statement.
if(strcmp(argv[1], "-L") == 0)
{
//does stuff
}
else if(strcmp(argv[1], "-W") == 0)
{
//does stuff
}
else if (*(argv[1]) != 1)
{
puts("error: invalid input");
}
else //should check if no arguments
{
puts("error: expected command line argument");
return 1;
}
I am getting a segmentation fault whenever there are no arguments from the command line, and I'm not sure how to fix it. I have also tried to write the else statement this way:
else if(argc < 2)
{
puts("error: expected command line argument");
return 1;
}
This was based on my previous research on here where I found "C produce error if no argument is given in command line," but it won't work either. I am a beginner in C and do not fully understand argc and argv, so if anyone has any suggestions or logic I'm completely overlooking, please let me know.
You need to check if argc < 2 before anything else.
Else you get segmentation fault because argv[index] could be something you have not privileges to access.
Whatever you do, make sure you never try to access an index of argv that is greater or equal to argc. In your case, you are accessing index 1 when the last available index is 0 (argc is 1), that's why the segmentation fault. See this post for more info: What does int argc, char *argv[] mean?

C Programming File I/O

I'm trying to read from a text file and write to one, but every time I execute my code, nothing happens with the text files. By "nothing happens", I mean that the program won't read my input file and no data is exported into my output file. Could someone point out why it is not working? Thanks for any help given in advance. Here is my code:
#include <stdio.h>
#include <stdlib.h>
FILE *inptr, *outptr;
int main() {
int a, b, c;
inptr = fopen("trianglein.txt","r"); //Initialization of pointer and opening of file trianglein.txt
outptr = fopen("triangleout.txt","w"); //Initialization of pointer and opening of file triangleout.txt
while((fscanf(inptr,"%d %d %d",&a, &b, &c))!= EOF){
fprintf(outptr,"\n%2d %2d %2d\n",a,b,c);
if(a+b>c && b+c>a && c+a>b){
fprintf(outptr, "This is a triangle.\n");
if(a !=b && b !=c && a!=c){
fprintf(outptr, "This is a scalene triangle.\n");
if(a==b && a==c && c==b){
fprintf(outptr, "This is an equilateral triangle.\n");
if(a*a+b*b==c*c || b*b+c*c==a*a || a*a+c*c==b*b){
fprintf(outptr, "This is a right trianlge.\n");
}
}
}
}
}
return 0;
}
trianglein.txt contents:
10 12 15
2 3 7
3 4 5
6 9 5
6 6 6
6 8 10
7 7 9
Multiple problems.
Firstly, you need to check if inptr and outptr are valid by testing against NULL.
Secondly, fscanf can return either EOF, 0 or > 0.
If your input file doesn't contain valid input.
Also there are problems in that you can get 3 ints read successfull, or 2 ints or 1 and the value of a, b and c are only optionally set.
If no conversion took place on the input then the value of zero is returned in which case the while loop will exit.
Also bear in mind that with the scanf style functions this input will succeed and return the value of 1.
"1rubbish"
I think what you may want is something like the following:
// Somewhere near the top
#include <stderr.h>
// ... other includes
const char* inname = "trianglein.txt";
const char* outname = "triangleout.txt";
// Any other stuff
// Inside main...
// Initialization of pointer and opening of file trianglein.txt
if ((inptr = fopen(inname,"r")) == 0){
fprintf(stderr, "Error opening file %s: %s", inname, strerror(inname));
return -1;
}
// Initialization of pointer and opening of file triangleout.txt
if ((outptr = fopen(outname,"w")) == 0){
fprintf(stderr, "Error opening file %s: %s", outname, strerror(outname));
return -1;
}
int result;
while(true){
result = fscanf(inptr,"%d %d %d",&a, &b, &c);
if (result == EOF)
break;
if (result < 3) // Ignore incomplete lines
continue;
// do the normal stuff
}
Your program is working fine in my system. I use Code::Blocks 10.05 on Windows 7.
The only possibility of a logical error occurs when you have the file trianglein.txt with less than 3 integer values to be read by the fscanf(). For example trianglein.txt file with values 1, 1 2, 1 2 3 4, 1 2 3 4 5 etc. will give incorrect values to the variables b and/or c. So initialize a=-1, b=-1, c=-1 before the execution of each iteration of the loop and check them after reading.
If you are running the program check the file triangleout.txt for access rights. Some times you may not have write access on that particular file.
By the way the classification logic is wrong. An equilateral triangle can not be a right angled one.
Try putting
fclose(inptr);
and
fclose(outptr);
at the end of your code.
EDIT: As suggested by icktoofay, this answer is wrong.
You have to do fclose() or fflush() in order to get the data written to the file.
Insert these code right before return 0;
fclose(inptr);
fclose(outptr);

GCC 4.7.0 run time issue - receiving signal 11 (SigSegv)

The following is a code snippet from my read from pipe function. This executes properly and verified that the data is got into buffer .
int readFrom(char *buffer)
{
int nread;
if((nread = read(readfd,buffer,100)) < 0)
{
printf("\nerror in reading data from FIFO\n");
return(-1);
}
buffer[nread]='\0';
return(0);
}
In the above example nread is less than 100 . I am using GCC-4.7.0.
We had an abstraction layer for the above function like below :
int pipe_input(char *parmPtr, int size)
{
char readMsg[100];
if( readFrom((char *)&readMsg) == -1)
return ERROR;
if (strlen(readMsg) < 1)
{
printf("Incorrect Input\n");
return ERROR;
}
strncpy(parmPtr, readMsg, ((size < 100)?size:100));
return 0;
}
In the above function as well it was verified that read message is proper and parmptr is properly loaded with the value. But in the function Where i am trying to call pipe_input I am getting a sigsegv. This happens with GCC-4.7.0 but the same code compiled with GCC-4.2.4 executes fine. I verified the warnings, but there are no warning for the above. Any pointers would be highly helpful.
Below code snippet for calling pipe_input :
int Calling_func(void)
{
char alpha[100] ;
pipe_input(alpha,100);
printf("alpha value is %s \r\n",alpha);
}
getting sigsegv at the print statement.
You have off-by-one errors in your code. Your array has 100 elements, but you're not taking NULL-termination into account:
strncpy(parmPtr, readMsg, ((size < 100)?size:100));
and:
buffer[nread]='\0';
The last element is buffer[99] (since array indices start from 0, not 1,) but you can write to buffer[100]. This can result in a segfault.
You should probably declare all arrays with a size of 101 instead and see if it helps. If you're on Linux, you should also run your program in Valgrind; it can tell you exactly how the segfault occurred.

Resources