So right now I'm trying to mess around with stdin and an input file by doing the following:
./a.exe < input.txt
The input.txt file just has a lot of random test cases so I can see if I'm doing this right or not. I'm trying to remove some punctuation marks from my input file through the use of stdin. You will notice that I have a couple of printf's laying in there saying "here". I put that there to see if the program reaches it or not.
So whenever I run it, I type "./a.exe < input.txt", and I get "bash: input.txt: No such file or directory". So I'm like... okay, I'll just type in a couple of random inputs to see if it works. I typed in random words, and it turns out the program doesn't even hit any of the words I typed after ./a.exe.
Can anyone explain why I'm having these errors?
Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
char textin[80], wordout[80];
int i, j;
int count = 0;
printf("%d", argc);
while (count != argc)
{
scanf("%s", textin);
if (strcmp(textin, ".") == 0)
printf("here");
printf("here2");
strcpy(wordout, textin);
for (i = 0 ; i < strlen(wordout) ; i++)
{
if (wordout[i] == '.' || wordout[i] == ',' ||
wordout[i] == '"' || wordout[i] == ';' ||
wordout[i] == '!' || wordout[i] == '?' ||
wordout[i] == '(' || wordout[i] == ')' ||
wordout[i] == ':')
{
for (j = i ; j < strlen(wordout) - 1 ; j++)
wordout[j] = wordout[j + 1];
wordout[j] = '\0';
}
printf("here3");
}
printf("%s\n", wordout);
count++;
}
return 0;
}
That first issue has nothing to do with your program, the error you're getting is a bash error, trying to open input.txt to connect to the standard input of your a.exe program. This happens before your code even begins to run.
You need to figure out why bash can't find your file, such as:
are you in the correct directory?
does the input.txt file actually exist?
have you created it in such a way that there are special characters in the file name (such as inpux<backspace>t.txt)?
As to the other issue, you appear to be using a mish-mash of two different methods of getting information from the user.
These two methods are arguments passed to the program (argc/v) and standard input (scanf()).
It may be that you're running your code with something like:
./a.exe arg1 arg2 arg3
and expecting it to do something with them. Unfortunately, the scanf() inside your loop will simply wait for you to type something on the terminal so it may seem that it has hung.
I think you need to figure out how you want to present the input to the program. If it's via arguments, you would use argv[N] where 1 <= N < argc. If it's via standard input, you probably don't need to concern yourself with argc/v at all.
Related
The user is supposed to pass some arguments when running the program, which have to have the following structure:
hanoiplus -d -f -o
They can write them in different order and they don't even have to write all of them. For example:
hanoiplus -f hello -d 3
But it will only work if there is the word hanoiplus at the beggining.
This is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define HPLUS "hanoiplus"
#define DCMD "-d"
#define FCMD "-f"
#define OCMD "-o"
int main(int narg, char**cmd) {
if(strstr(HPLUS,cmd[1])){
for(int i=2; i <= narg; i++){
if(strstr(DCMD,cmd[i]) && i<narg){ /*EXECUTE -d COMMAND IF SPECIFIED*/
i++; //Increase i by 1 to go to the next command
printf("INPUT: %s %s",cmd[i-1],cmd[i]); //Change the number of disks to cmd[i]
}else if(strstr(FCMD,cmd[i]) && i<narg){ /*EXECUTE -f COMMAND IF SPECIFIED*/
i++;
printf("INPUT: %s %s",cmd[i-1],cmd[i]);
create_file(cmd[i]);//Call the function that creates an external file
}else if(strstr(OCMD,cmd[i]) && i<narg){ /*EXECUTE -o COMMAND IF SPECIFIED*/
i++;
printf("INPUT: %s %s",cmd[i-1],cmd[i]);
create_object(cmd[i]);//Call the function that calls the writing operation
}
}
return 1; //The command(s) is/are valid.
}else{
return 0; //The command is not valid.
}
}
All the commands are saved as elements of char **cmd.
First of all, the program checks if the second command is "hanoiplus" -since the first command is always a path that I'm not interested in- and then it executes a for loop that iterates over **cmd as many times as elements **cmd has.
In each iteration, the program checks what command has been entered and it calls the function that carries out what the command represents.
The program also prints the input, so I can check if the arguments are being passed correctly.
Though the first iteration of the loop goes well, the second time the program crashes and it shows a segmentation fault.
Does anyone have any idea of what it is happening?
Thank you.
these expressions cause your program to access an no-existing argument cmd[narg].
if(strstr(DCMD,cmd[i]) && i<narg)
So, strstr might crash because of it. you need to swap the terms in the expression to avoid the issue:
if(i < narg && strstr(DCMD,cmd[i]))
or use i < narg in the loop.
I have only Java experience, and I'm starting to learn C through the K&R C book, second addition. In the first chapter, one of their examples is this program which simply counts the white space, characters, and digits:
#include <stdio.h>
main()
{
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
for(i = 0; i < 10; i++){
ndigit[i] = 0;
}
while((c = getchar()) != EOF){
if(c >= '0' && c <= '9'){
++ndigit[c-'0'];
}
else if (c == ' ' || c == '\n' || c == '\t'){
++nwhite;
}
else{
++nother;
}
}
printf("digits =");
for(i = 0; i <10; ++i){
printf(" %d", ndigit[i]);
}
printf(", white space = %d, other = %d\n", nwhite, nother);
}
Next, in the book they say "the output of this program run on itself is " followed by its output. However, I've compiled the program in the terminal and just cannot figure out how to run this program on itself in C. In java, I would have passed the file name to String args[0] and read it from there, but this program doesn't have any similar mechanism, and doesn't seem to have an args array to pass to. Even if it did, the code itself doesn't seem to read from any particular file (for example, in java you could specifically set up a scanner to read args[0], and then call scanner.next() etcetc, but in this program, it just calls getchar() on seemingly nothing). Can anyone help me clear this up so I can run the program before continuing? Sorry if this is something super simple, like I said my experience in C is nonexistent. Thank you!
Also my formatting on this website is trash I apologize
I assume they intend to run this program like so:
./example < example.c
You are correct about the fact that the program does not open a file and it does not use arguments. The getchar() function operates on stdin.
The program does not make much sense if you use it on the compiled file, so that is why I assumed it is supposed to be run with the source file. I see how the instructions are confusing.
I'm a beginner in C, and I've got problem I can't figure out, and wasn't able to find a solution on other threads here.
I'm trying to read integers from a keyboard input/ txt file with the following code:
int grades[MAX_GRADES_LENGTH]={0}, histogram[HISTOGRAM_SIZE]={0};
int maxGradesHistogramBucket=0, median=0, gradesLength=0;
double avg=0.0;
int grade=0;
printf("Enter grades:\n");
while (scanf("%d",&grade) != EOF)
{
grades[gradesLength]=grade;
gradesLength=gradesLength+1;
}
I'm supposed to set these "grades" in the grades[] array and count the length of the array along the loop.
Somehow the loop is misbehaving, it seems that some inputs are ok with the loop, but for some inputs(most of them actually) the scanf() doesn't get the EOF, whether it's an actual end of file, or the ^D command in the terminal.
I've heard the scanf() is not the most reliable method to read data, but unfortunately I can't use anything else since we haven't learned any other method in class so we can only use scanf() on our homework.
I've tried to change the!= EOF with == 1 and its all the same.
for the input
100 0 90 10 80 20 70 30 60 40 50
for example it works fine.
but for the input:
0 50 100
the loop is infinite.
I'm using a macbook pro btw (if it matters).
Any ideas?
If you type a letter instead of a number, scanf() will return 0 (as in, "zero successfully converted numbers") and not EOF (as in, "there was no data left to read"). The correct test is to ensure that you got the expected number of values — in this case, 1:
while (scanf("%d", &grade) == 1)
If you need to know whether you got to EOF or got no result (but reading the rest of the line might clear the problem), then capture the return value from scanf():
int rc;
while ((rc = scanf("%d", &grade)) == 1)
{
}
if (rc != EOF)
…read the rest of the line, or at least the next character, before resuming the loop…
And, if you really want to, you could then write:
int rc;
while ((rc = scanf("%d", &grade)) != EOF)
{
if (rc == 1)
grades[gradesLength++] = grade;
else
{
printf("Discarding junk: ");
int c;
while ((c = getchar()) != EOF && c != '\n')
putchar(c);
putchar('\n');
if (c == EOF)
break;
}
}
The code in the else clause could plausibly be put into a function. It might also report the messages to standard error rather than standard output. It is courteous to let the user know what it was that you objected to. You could stop before newline with a different test (&& !isdigit(c) && c != '+' && c != '-', using isdigit() from <ctypes.h>). However, the user doesn't have a chance to re-edit the stuff they put after the letters, so you may be going to misinterpret their input. It is probably better just to throw away the rest of the line of input and let them start over again.
As chux noted, after reading a character that could be part of an integer, that character needs to be put back into the input stream. Therefore, if I were going to analyze the rest of the line and restart scanning at the first data that could actually be part of an integer, I'd consider using something like:
#include <ctype.h>
static inline int could_be_integer(int c)
{
return isdigit(c) || c == '+' || c == '-');
}
and then the else clause might be:
else
{
printf("Discarding junk: ");
int c;
while ((c = getchar()) != EOF && c != '\n' && !could_be_integer(c))
putchar(c);
putchar('\n');
if (could_be_integer(c))
ungetc(c, stdin);
else if (c == EOF)
break;
}
This gets messy, as you can see. Sometimes (as Weather Vane noted in a comment), it is easier to read a line with fgets() and then use sscanf() in a loop (see How to use sscanf() in a loop?). Be wary of suggestions about Using fflush(stdin); it isn't automatically wrong everywhere, but it won't work on a MacBook Pro under normal circumstances.
On the whole, simply ignoring the rest of the line of input is usually a better interface decision.
It works for me.
I enclosed your snippet thus:
#include <stdio.h>
#include <errno.h>
#define MAX_GRADES_LENGTH 20
#define HISTOGRAM_SIZE 20
main()
{
int grades[MAX_GRADES_LENGTH]={0}, histogram[HISTOGRAM_SIZE]={0};
int maxGradesHistogramBucket=0, median=0, gradesLength=0;
double avg=0.0;
int grade=0;
int i;
printf("Enter grades:\n");
while (scanf("%d",&grade) != EOF)
{
grades[gradesLength]=grade;
gradesLength=gradesLength+1;
}
if (errno)
perror("grade");
for (i = 0; i < gradesLength; ++i) {
printf("%d\n", grades[i]);
}
}
and ran it:
$ a.out
Enter grades:
100 0 90 10 80 20 70 30 60 40 50
100
0
90
10
80
20
70
30
60
40
50
$ a.out
Enter grades:
0 50 100
0
50
100
$
Perhaps you are looking in the wrong place. Maybe the bug is in your output routine?
Personally, if had to do this, given some ambiquity over what scanf returns when, and without rewriting it, then this small change is probably more reliable:
int i, r;
printf("Enter grades:\n");
while ((r = scanf("%d",&grade)) > 0)
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])
I am working on a program to filter a list of craigslist results; I want to find a relatively cheap room for rent. The finished program will remove lines that have a price over $600, and create a new file, but for now I am removing every line with a $ character, and printing to the terminal.
The program works fine when run on its own source, but when I run it on an html page of craigslist results saved from Firefox, it prints until the closing html bracket and throws a stack smashing detected warning and a backtrace. I am learning C from K&R so if this code looks antiquated that's why.
# include <stdio.h>
# define MAXLINE 300
main()
{
char line[MAXLINE];
int c;//current character
int p = 0;//position in the line
int flag = 0;//there is a dollar sign
while ((c = getchar()) != EOF){
line[p++] = c;
if (c == '$'){
flag = 1;
}
if (c == '\n'){
if(flag == 0){//there was no $, print the line
int i;
for(i=0;i<p;i++){
putchar(line[i]);
line[i] = '\0';
}
}
p = 0;
flag = 0;
}
}
}
I imagine the problem is just that the HTML contains at least one line that is more than MAXLINE characters long. You don't check anywhere whether you're about to exceed the size of the array; if you do, you would indeed smash the stack. Your while loop could check whether p was less than MAXLINE, print a message if not, and stop. You couldn't do anything else without fairly significant changes to your program.