C - Error while running .exe file that I compiled - c

I used geany to compile my code and no errors were found.
But when I run the .exe file the program stops working, and I'm not a good programmer, this is a work for school.
My program consists of reading 2 words, in this words its going to count how many letters each one has, and then he divides de number of letters in wordA for number of letters in wordB.
This is my code
#include <stdio.h>
int main(int argc, char *argv[])
{
int i, j;
float n;
printf ("Insert first word:\n");
for(i=0; argv[1][i] != '\0'; i++);
printf ("Insert second word:\n");
for(j=0; argv[2][j] != '\0'; j++);
n=i/j;
printf("%.4f", n);
return 0;
}

In this line
n = i/j;
you are performing integer division. So, for example, let's say that i is 3 and j is 5, then you perform 3/5 which equals 0.
But I think you are looking to perform 3.0/5.0 and hoping for the answer 0.6. So you need to perform floating point division. You can force that by casting one of the operands to a float.
n = (float)i/j;
In the question you wrote Int rather than int. I assumed that was a transcription error when asking the question. But perhaps your real code looks like that. In which case, you'll need to change it to int to get it to compile.
The other possible problem you have is that the program expects arguments to be passed on the command line. Are you passing two arguments to your program? In other words you need to execute your program like this:
program.exe firstword secondword
If you are not passing arguments then you will encounter runtime errors when attempting to access non-existent arguments in argv[]. At the very least you should add a check to the program to ensure that argc==3.
If you want to read the input from stdin, rather than passing command line arguments, use scanf.

I think this is a conceptual error. Your program (probably) runs fine when called like this:
myapp word1 word2
But I think you expect it to work like this:
myapp
Insert first word:
> word1
Insert second word:
> word2
But that's not what argv is about. You should look into scanf
Specifically, the error in the second case is because argv[1] is NULL, so argv[1][i] is a bad memory access.

Related

Can someone explain to me how does this actually work (atoi)

I have written a program that takes 2 arguments from the user and adds them together so for example if the user puts ./test 12 4 it will print out the sum is: 16.
the part that is confusing me is why do I have to use the atoi and I can't just use argv[1] + argv[2]
I know that atoi is used convert a string to an integer and I found this line of code online which helped me with my program but can someone explain to me why do I need it :
sum = atoi(argv[1])+atoi(argv[2]);
code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int sum = 0;
sum = atoi(argv[1])+atoi(argv[2]);
printf("The sum is : %d \n", sum);
return 0;
}
The reason is the same thing as the difference between you and your name. The user typed "./test 12 4" so before your program ran, the command shell that the user is using prepared two sequences of numbers representing the text characters that form the names of the user's numbers and gave them to your program - the shell got those directly from the terminal where the user typed them.
In order to add the numbers that these sequences identify by name you need to use a function that converts those two names to int - a representation of the numbers that they identify for which addition is defined. This function is called 'atoi' and the two names were the sequences {49,50,0} and {52,0} (being representations of the symbol sequences {'1','2','\0'} and {'4', '\0'}). The 0 (also written '\0') is a code for a special symbol that can't be printed or typed directly (this is a lie but I don't want to get into that) and it's added to the end of the names so that atoi, as it reads the name character code by character code, knows when it reached the end. Note that these particular values depend on what platform you're using but I'm assuming it's a platform that uses ascii or utf-8 rather than something like ebcdic.
As part of printing the resulting number, printf uses the "%d" directive to accept the int way of representing the answer (which you got from adding two ints) and converts it back to to the name of the answer as character codes {49,56} ({'1','6'}) ready to send back to the terminal. I left out any possible terminating 0 ('\0') in the output codes just there because printf doesn't indicate an end here unlike the end indications you receive in the inputs from the shell - the terminal can't look for an end in the same way that atoi does and printf doesn't give you the name for further usage within the C program; it just sends the name right out of the program for display to the terminal (which is the place that the command shell hooked up to the program's output stream).
Although atoi isn't the only thing you could do with the incoming names for numbers, the C language has been designed to give the ending marker for each argv element because it will typically be needed for any alternative choices you might make for handling the incoming information.
Try this to see the codes being used explicitly (still assuming your system uses ascii or utf-8):
#include <stdio.h>
#include <stdlib.h>
char const name_of_program[] = "./test";
char const name_of_first_number[] = {49,50,0}; // {'1','2','\0'} would be the same as would "12" - with the quotes
char const name_of_second_number[] = {52,0}; // {'4','\0'} would be the same as would "4" - with the quotes
int main()
{
char const *argv[] = {
name_of_program,
name_of_first_number,
name_of_second_number,
NULL,
};
int sum = 0;
sum = atoi(argv[1])+atoi(argv[2]);
printf("The sum is : %d \n", sum);
return 0;
}
"the part that is confusing me is why do i have to use the "atoi" and i can't just use argv[1] + argv[2]"
The argv argument holds a list of strings that the program can take as input. The C language does not automatically convert strings to numbers, so you have to do that yourself. The atoi function takes a string as a parameter and returns an integer, which can then be used for the arithmetic operations you want.
In other languages such as C++, summing strings usually concatenates them, but in C you will get a compiler error.
Your argv[i] is type C string by default:
int main(int argc, char *argv[])
and sum is type int.
Even if you input a number it will be read as a char* by your compiler. atoi() makes it read as an int so you can do arithmetic calculations with it.
[Answer updated thanks to comments bellow]

Error: expected declaration specifiers or '...' before string constant [puts() and gets() statement errors

After compiling my program of Dice Roll, I got this error. What is wrong with the code?
Also before I was using gets() instead of scanf() command, but because of that I got this error - passing argument 1 of 'gets' makes pointer from integer without a cast
So I removed the gets() command and used scanf and then there was no error regarding scanf().
What is the reason for getting these two errors?
Ok, so as per the answer I got to know how I should have used the gets() command and why I shouldn't use it instead should use scanf(). So, I made the changes.
Though I have encountered two new errors, this time it's related to the delay() command that I used.
Errors: undefined reference to delay
|error: ld returned 1 exit status|
OK so I solved my last errors by using Sleep() command from windows.h library instead of Delay() command. The programs was compiled.
But still there is a runtime error in the program, it works well till getting the roll1 but then it just print the next two statement and terminated the programs without taking a input for the guess.
It skips all the code after printf("Will it be Higher/Lower or the same? (press H/L/S)\n"); and directly terminates the program.
Ok So I solved above problem adding a whitespace before the "%c" in scanf(" %c", &nextGuess); statement. (Little things xD)
Now only problem is that my toupper() command is not working.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <windows.h>
int main()
{
int i, roll1=0, roll2=0, NumberOfRolls, RandomNUM1[50], RandomNUM2[50];
char nextGuess;
puts("Welcome to the Dice Roll Game");
puts("How many times do you want to roll a dice?");
scanf("%d", &NumberOfRolls);
for( i=1; i<=NumberOfRolls; i++ ) {
RandomNUM1[i] = ( rand()%6 ) + 1;
roll1 += RandomNUM1[i];
}
printf("\nYou Got %d in your first roll!\n", roll1);
Sleep(3000);
printf("\nLet's see if you can guess the value of next roll.\n");
printf("Will it be Higher/Lower or the same? (press H/L/S)\n");
scanf(" %c", &nextGuess);
toupper(nextGuess);
for( i=1; i<=NumberOfRolls; i++ ) {
RandomNUM2[i] = ( rand()%6 ) + 1;
roll2 += RandomNUM2[i];
}
if(nextGuess=='H'){
if(roll1<roll2){
printf("You are such a player, you guessed it right! It's %d", roll2);
}
else if(roll1>roll2){
printf("Uh-Oh! Bad Luck! First roll was higher, It's %d", roll2);
}
else if(roll1==roll2){
printf("Uh-Oh! Bad Luck! Both the rolls are same, It's %d", roll2);
}
}
if(nextGuess=='L'){
if(roll1>roll2){
printf("You are such a player, you guessed it right! It's %d", roll2);
}
else if(roll1<roll2){
printf("Uh-Oh! Bad Luck! First roll was lower, It's %d", roll2);
}
else if(roll1==roll2){
printf("Uh-Oh! Bad Luck! Both the rolls are same, It's %d", roll2);
}
}
if(nextGuess=='S'){
if(roll1==roll2){
printf("You are such a player, you guessed it right! It's %d", roll2);
}
else if(roll1>roll2){
printf("Uh-Oh! Bad Luck! First roll was higher, It's %d", roll2);
}
else if(roll1<roll2){
printf("Uh-Oh! Bad Luck! Second roll is higher, It's %d", roll2);
}
}
return 0;
}
You have a stray ,
At the 2nd line of your main, you declare char nextGuess, instead of char nextGuess;
The compiler tells you it expects specifiers or ... after , so either you add these, or you end the line properly with;.
And for the other problem you mention:
passing argument 1 of 'gets' makes pointer from integer without a cast
Since gets argument should be char *str and you didn't provide it.
You can fix that by, for example:
char tmp_NumberOfRolls[10];
gets(tmp_NumberOfRolls);
NumberOfRolls = atoi(tmp_NumberOfRolls);
but I prefer the scanf solution
PS: (in a now edited version of the code) ***//Error Line*** is not a comment (at least, not all of it) since the *** is still counted as part of the code and will cause an error. Either move the // a bit to the left or enclose that whole part with /* ... */
The gets function reads a string (till the next newline character) from stdin, therefore it asks for a char pointer (char*) to an area of memory where it can put all the characters read including string terminator. The mistake you made is to pass to that function a pointer to int, therefore not only you get a compiler error because you tried to pass an int pointer to gets (for which there are none implicit conversions), but even if it compiled, it would not have worked as you expected because it would put all the characters (which have a size of one byte - most of the times) in that area of memory encoded as chars. That means that when you try to dereference one using a pointer to int, the characters are "read like they were an int"!
There is an example (supposing 1-byte chars, 4-bytes int and a little endian machine and that there is an implicit cast from int* to char* which does not exist and hopefully will never exist):
int num
gets(&num);
if I input 123 in stdin, the memory area pointer by num is large enough to contain the string, but it would contain (exadecimal representation):
0x31|0x32|0x33|0x00
because the string is 3 characters long, ASCII code for '1' is 0x31, for '2' is 0x32, and for '3' is 0x33 and terminates with '\0'!!
Then, when you try to dereference it you get this int (binary representation - supposing a little endian machine):
00000000|00110001|00110010|00110011
which is not the int value 123 but instead ‭3224115‬. Which is not what you wanted to get.
When you use the scanf function, you pass to that function a format string which tells it how to interpret the next arguments passed to it and performs the appropriate conversions between the string read to the right type you specified. That means that you should still pay attention to what you tell to the scanf function while you write the format string (if you tell it to read a string and pass to it a pointer to int, the program will probably crash), but it performs the appropriate conversions for you, if you write the format string correctly.
That's why with scanf everything works perfectly (you're reading an int and you specified "%d" as format string), whereas with gets it does not compile to avoid serious mistakes.
I also would like to remark some points of this answer:
The example is just for didactic purposes and the code provided does not work indeeed. The fact that I supposed that it compiles is for didactic purposes; obviously, the code provided in that example does not compile
If, in that example, we input a string larger than 3 characters (which are four if we include the null terminator) or the int (char) type contains less (more) than 4 (1) byte, the program would have crashed because we corrupted other areas of memory
The reference is more expert than me in techincal stuff, so here are the links to the gets function and the scanf function: gets, scanf (and the ASCII Table is useful too)
You could use the gets function together with the atoi function to parse the string read from gets (using a char pointer to a free area of memory large enough to contain the string, which is pretty hard to allocate (*)) to an int, but scanf is the best approach.
(*) Remember: if you allocate an area of memory that contains 20 chars, the user will input 21 chars. The atoi function fails, but the worst thing is that you have a buffer overflow (and can be a high security issue if your program runs under root permissions).

C: Segmentation Fault when reading from a file

I recently started working on this project, and I'm having trouble reading certain things into a global variable. It's for practice with pthreads, which is why I'm using a global variable in the first place. The program is supposed to read in numbers from a file that represent a solved sudoku puzzle, and the text file will be formatted with 9 number characters followed by a new line, nine times. I've made sure that, when running this program, the file is formatted as such. I know that this segment of my code contains the segmentation fault, but I can't tell where. I can only presume that it has something to do with fgets(). However, none of the resources I looked up have anything in them that would make me think that I'm using it incorrectly. It even does this when I resort to using fgetc, reading it in one bit at a time, making accomodations for fgetc returning an int, unlike fgets assigning a string to a variable (in this case, s).
I wouldn't bring it to stack overflow unless I was sure that I couldn't find it; I've been combing over the code for an hour trying to find this seg fault, and it doesn't make any sense to me. I know that the Seg Fault is here because directly after it, it should print out the entire puzzle matrix, but it doesn't make it that far.
int main(int argc, char *argv[]) {
FILE* puzzlefile;
char s[10];
int i=0, j=0, skip;
//open the file passed in via command line
puzzlefile = fopen(argv[1], "r");
for (i=0; i<9; i++){
//get first string of 10 characters
fgets(s,10, puzzlefile);
for (j=0; j<9; i++){
//read the numbers from s into the puzzle 2D
//array, which takes ints. Ignore the 10th
//character, which will be \n
puzzle[j][i] = (int)(s[j]-'0');
}
}
...
}
Your problem seems to be this:
for (j=0; j<9; i++)
^^^
This should be j++, not i++

getting numbers from stdin to an array in C

I'm trying to get numbers from stdin to an array. the first number in stdin is the number of elements in the array (the number can be any int).
I did this to get the first number:
while(c=getchar()!=' '){
n*=10;
n+=atoi(c);
}
And then created an array of size n.
Now I need to go through all the rest
while(c=getchar()!=EOF)
and add numbers to the array. The numbers are separated by \t and sometimes \n as well.
How would I do that? I've been thinking for an hour and still haven't got a working code.
Any help?
Thanks!
Unless you're feeling particularly masochistic (or can't due to homework requirements), you'd normally do it using scanf:
int n;
int *numbers;
scanf("%d", &n);
numbers = malloc(n * sizeof(*numbers));
for (int i=0; i<n; i++)
scanf("%d", &numbers[i]);
For more robust error handling, you frequently want to read a line at a time using fgets, then parse that into individual numbers using sscanf (or something similar).
As an aside: no you should not cast the return from malloc to int *. It's neither necessary nor desirable in C. Just #include <stdlib.h>, and assign the result as shown above. If your compiler is giving you a warning (or error) about a conversion, that means one of two things is happening: either you've forgotten to #include <stdlib.h> as required, or else you're actually compiling as C++. If you're writing C++, write real C++, which means you shouldn't be using malloc at all.

Arguments to main in C [duplicate]

This question already has answers here:
Pass arguments into C program from command line
(6 answers)
Closed 6 years ago.
I don't know what to do! I have a great understanding of C basics. Structures, file IO, strings, etc. Everything but CLA. For some reason I cant grasp the concept. Any suggestions, help, or advice. PS I am a linux user
The signature of main is:
int main(int argc, char **argv);
argc refers to the number of command line arguments passed in, which includes the actual name of the program, as invoked by the user. argv contains the actual arguments, starting with index 1. Index 0 is the program name.
So, if you ran your program like this:
./program hello world
Then:
argc would be 3.
argv[0] would be "./program".
argv[1] would be "hello".
argv[2] would be "world".
Imagine it this way
*main() is also a function which is called by something else (like another FunctioN)
*the arguments to it is decided by the FunctioN
*the second argument is an array of strings
*the first argument is a number representing the number of strings
*do something with the strings
Maybe a example program woluld help.
int main(int argc,char *argv[])
{
printf("you entered in reverse order:\n");
while(argc--)
{
printf("%s\n",argv[argc]);
}
return 0;
}
it just prints everything you enter as args in reverse order but YOU should make new programs that do something more useful.
compile it (as say hello) run it from the terminal with the arguments like
./hello am i here
then try to modify it so that it tries to check if two strings are reverses of each other or not then you will need to check if argc parameter is exactly three if anything else print an error
if(argc!=3)/*3 because even the executables name string is on argc*/
{
printf("unexpected number of arguments\n");
return -1;
}
then check if argv[2] is the reverse of argv[1]
and print the result
./hello asdf fdsa
should output
they are exact reverses of each other
the best example is a file copy program try it it's like cp
cp file1 file2
cp is the first argument (argv[0] not argv[1]) and mostly you should ignore the first argument unless you need to reference or something
if you made the cp program you understood the main args really...
For parsing command line arguments on posix systems, the standard is to use the getopt() family of library routines to handle command line arguments.
A good reference is the GNU getopt manual
Siamore, I keep seeing everyone using the command line to compile programs. I use x11 terminal from ide via code::blocks, a gnu gcc compiler on my linux box. I have never compiled a program from command line. So Siamore, if I want the programs name to be cp, do I initialize argv[0]="cp"; Cp being a string literal. And anything going to stdout goes on the command line??? The example you gave me Siamore I understood! Even though the string you entered was a few words long, it was still only one arg. Because it was encased in double quotations. So arg[0], the prog name, is actually your string literal with a new line character?? So I understand why you use if(argc!=3) print error. Because the prog name = argv[0] and there are 2 more args after that, and anymore an error has occured. What other reason would I use that? I really think that my lack of understanding about how to compile from the command line or terminal is my reason for lack understanding in this area!! Siamore, you have helped me understand cla's much better! Still don't fully understand but I am not oblivious to the concept. I'm gonna learn to compile from the terminal then re-read what you wrote. I bet, then I will fully understand! With a little more help from you lol
<>
Code that I have not written myself, but from my book.
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
printf("The following arguments were passed to main(): ");
for(i=1; i<argc; i++) printf("%s ", argv[i]);
printf("\n");
return 0;
}
This is the output:
anthony#anthony:~\Documents/C_Programming/CLA$ ./CLA hey man
The follow arguments were passed to main(): hey man
anthony#anthony:~\Documents/C_Programming/CLA$ ./CLA hi how are you doing?
The follow arguments were passed to main(): hi how are you doing?
So argv is a table of string literals, and argc is the number of them. Now argv[0] is
the name of the program. So if I type ./CLA to run the program ./CLA is argv[0]. The above
program sets the command line to take an infinite amount of arguments. I can set them to
only take 3 or 4 if I wanted. Like one or your examples showed, Siamore... if(argc!=3) printf("Some error goes here");
Thank you Siamore, couldn't have done it without you! thanks to the rest of the post for their time and effort also!
PS in case there is a problem like this in the future...you never know lol the problem was because I was using the IDE
AKA Code::Blocks. If I were to run that program above it would print the path/directory of the program. Example: ~/Documents/C/CLA.c it has to be ran from the terminal and compiled using the command line. gcc -o CLA main.c and you must be in the directory of the file.
Main is just like any other function and argc and argv are just like any other function arguments, the difference is that main is called from C Runtime and it passes the argument to main, But C Runtime is defined in c library and you cannot modify it, So if we do execute program on shell or through some IDE, we need a mechanism to pass the argument to main function so that your main function can behave differently on the runtime depending on your parameters. The parameters are argc , which gives the number of arguments and argv which is pointer to array of pointers, which holds the value as strings, this way you can pass any number of arguments without restricting it, it's the other way of implementing var args.
Had made just a small change to #anthony code so we can get nicely formatted output with argument numbers and values. Somehow easier to read on output when you have multiple arguments:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("The following arguments were passed to main():\n");
printf("argnum \t value \n");
for (int i = 0; i<argc; i++) printf("%d \t %s \n", i, argv[i]);
printf("\n");
return 0;
}
And output is similar to:
The following arguments were passed to main():
0 D:\Projects\test\vcpp\bcppcomp1\Debug\bcppcomp.exe
1 -P
2 TestHostAttoshiba
3 _http._tcp
4 local
5 80
6 MyNewArgument
7 200.124.211.235
8 type=NewHost
9 test=yes
10 result=output

Resources