I am trying to get a integer value from argv[1].
I want to know what happens if the user inputs a character so that I can avoid it. I tried '\0' and currently this doesn't work.
int main(int argc, char* argv[]){
int MAX_SIZE;
MAX_SIZE=atoi(argv[1]);
while(MAX_SIZE=='\0'){
printf("plz input in correct format: ");
scanf("%d", &MAX_SIZE);}
Any help would be appreciated.
Your code is a bit weird but from what I understand you want to check if a character is a number or not, for that you can use the function isdigit() to check if the entered value is a number or not, something like this:
char c='a';
if(isdigit(c)) //if true, i.e. it returns non-zero value
cout<<"number";
else // if false, i.e. it returns zero
cout<<"Char";
I have written C++ code as I am more comfortable in C++ but the function isdigit() works in both C and C++.
# include <stdio.h>
# include <stdlib.h>
int main ( int argc, char *argv[] )
{
int i, n, a;
printf("\n argv[0] = %s\n", argv[0] );
if ( argc <= 1 )
{
printf("\n");
printf(" argc = %d, no arguments given on command line\n", argc );
printf("\n");
}
for ( i = 1; i < argc; i++ )
{
n = sscanf( argv[i], "%d", &a );
if ( n == 1 )
{
printf(" read %d off command line in argv[%d]\n", a, i );
}
else
{
printf(" sscanf failed, n = %d, argv[%d] = %s\n", n, i, argv[i] );
}
}
return 0;
}
Related
How to use isdigit function in C to check whether the given multiple digit string is numeric or not?
This is how I used isdigit function for a single digit character.
#include<stdio.h>
#include<cs50.h>
#include<ctype.h>
int main()
{
char c = get_char("Enter a single character:");
int a = isdigit(c);
if ( a != 0)
{
printf("%c is an integer \n", c);
}
else
{
printf("%c is not an integer \n",c);
}
}
Now, I want to check for the multiple digit character(eg. 92, 789). here is my code
#include<stdio.h>
#include<cs50.h>
#include<string.h>
#include<ctype.h>
int main()
{
string num = get_string(" Enter a number:");
int final = 1;
for(int i =0; i< strlen(num); i++)
{
// final = final * isdigit(num(i));
final*= isdigit(num[i]);
}
if(final!=0)
{
printf("%s is an integer.\n", num);
}
else
{
printf("%s is not an integer.\n", num);
}
}
However, the above code only works for two digit integer , but not for 3 digit integer. See this:
Compiled Code SS
The isdigit function isn't required to return a boolean 0 or 1 value. It's specified to return zero if the character isn't a digit, and any non-zero value if it is a digit.
Take for example the implementation used by here. We can see that isdigit returns 2048.
Because it returns that value, the multiplication will lead to a signed integer arithmetic overflow, which in turn leads to undefined behavior.
Instead I suggest you use isdigit directly in a condition, and if it returns 0 then print the message and terminate the program:
size_t length = strlen(num);
if (length == 0)
{
printf("String is empty\n");
return EXIT_FAILURE;
}
for (size_t i = 0; i < length; ++i)
{
if (isdigit(num[i]) == 0)
{
printf("Input was not a number\n");
return EXIT_FAILURE;
}
}
// Here we know that all characters in the input are digits
You could simply replace the multiply operation with &... Once a non-digit appears and isdigit() returns 0 (meaning false), the flag variable will remain false.
You may want to consider combining operations into compact code such as the following.
#include <stdio.h>
#include <ctype.h>
#include <cs50.h> // less "generic" that the others
int main( void ) {
string num = get_string(" Enter a number:");
int i = 0;
while( isdigit( num[i] ) ) i++; // loop fails on '\0', too
if( i == 0 || num[i] ) // empty string or did not reach its end
printf( "%s is NOT an integer.\n", num );
else
printf( "%s is an integer.\n", num );
return 0;
}
There is an array of n students( stu[n]).If gender is boy then my code adds
for boy b, 2nd,4th,6th,........even position elements of array and
for girl g, 1st,3rd,5th....odd position elements of array.
1> Gender of boys denoted by b.
2> Gender of girls denoted by g.
Input info>>
The 1st line contains n, denoting the number of students in the class, hence the number of elements in the array.
Each of the subsequent lines contains the marks of n students .
The last line contains gender b/g;
Output info>>
The output should contain the sum of all the alternate elements of marks as explained above.
#include <stdio.h>
int main() {
int n,i;
scanf("%d",&n);//n denotes number of students.
int stu[n],sum=0;
for(i=1;i<=n;++i)
scanf("%d",&stu[i]);//for accepting input in array.
char gen;
scanf("%s",&gen);//for accepting input gender b/g.
for(i=1;i<=n;i++){
if(gen=='g' && i%2!=0){ //girl g adds alternate odd position elements.
sum=sum+stu[i];
printf("%d",sum);
}
else if(gen=='b' && i%2==0){ //boy b adds alternate even position elements.
sum=sum+stu[i];
printf("%d",sum);
}
}
//code
return 0;
}
Sample Input
3
3
2
5
b
Sample Output
8
explanation>>
marks=[3,2,5] and gender = b so it will add 3+5(even position 0,2 alternate elements). If gender in place of b is g then it will produce output = 2.
My code is shows output of 0 in all test cases.
You have the major problem in
int n,i;
int stu[n],sum=0;
here, n being a uninitialized local scoped variable with automatic storage, the initial value is indeterminate.
Now, since the address of the variable was never taken and it has a type that can have trap representation, attempt to use the value (int stu[n]) will invoke undefined behavior.
You need to scan in the value into n first, then use that to define the VLA stu. Something like
int n,i;
scanf("%d",&n);//n denotes number of students.
// **Note: please check for errors in input with scanf return value.**
int stu[n],sum=0; // here, n has the scanned value.
That said,
char gen;
scanf("%s",&gen);
is also horribly wrong, you want to scan in a char, not a string, and with the address of a plain char variable, %s conversion specification would be UB, again. You should use %c and discard any whitespaces which is present in buffer altogether.
You're making things more complicated than they need to be. Here is how you can possibly do:
#include <stdio.h>
int main(void)
{
int mark;
int b = 0;
int g = 0;
char students_marks[5];
for (int i=0; i<5; i++) {
scanf("%d", &mark);
students_marks[i] = mark;
}
for (int i=0; i<5; i++) {
if (i%2 == 0) b += students_marks[i];
if (i%2 == 1) g += students_marks[i];
}
printf("Boys: %d\nGirls: %d\n", b, g);
return 0;
}
You should probably not use an array, and just ignore the first data point. It is (probably) easier to use a linked list. Or maybe just use two lists, alternating the inputs between them. And I would definitely not use scanf. If you are new to C, do NOT waste your time learning the foibles of the scanf format string language. The only time scanf is ever useful is in introductory courses where instructors incorrectly believe that you will be able to get input more quickly than if you spend time learning other methods. But in fact you will end up burning more time learning when to use spaces in the format string that you saved by not learning fread. After your introduction to C, you will (almost) never use scanf. Also, it seems like a horrible design to put the discriminant at the end of the input. The values to be summed (the gender) should be given as a command line argument. That said, you could just do:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
FILE *
xfopen(const char *path, const char *mode)
{
FILE *rv;
if( (rv = fopen(path, mode)) == NULL ) {
perror(path);
exit(EXIT_FAILURE);
}
return rv;
}
int
main(int argc, char **argv)
{
int i;
int size; /* Should probably be size_t. Skipping that for now. */
FILE *in = argc > 1 ? xfopen(argv[1], "r") : stdin;
int sum = 0;
if( fscanf(in, "%d", &size) != 1 || size <= 0 ) {
fprintf( stderr, "invalid input\n" );
exit(EXIT_FAILURE);
}
int grades[size];
for( i = 0; i < size; i++ ) {
if(fscanf(in, "%d", grades + i) != 1) {
fprintf( stderr, "invalid input on line %d\n", i );
exit(EXIT_FAILURE);
}
}
char gender;
if(fscanf(in, " %c", &gender) != 1) {
fprintf( stderr, "invalid input on line %d\n", i );
exit(EXIT_FAILURE);
}
if(strchr("bBgG", gender) == NULL) {
fprintf( stderr, "invalid gender: %c\n", gender);
exit(EXIT_FAILURE);
}
for( i = tolower(gender) == 'b'; i < size; i += 2 ) {
sum += grades[i];
}
printf("sum: %d\n", sum);
}
Hmm… i changed your code a Little bit and hope this runs as described.
int main() {
int n, index, sum=0;
int* stu;
scanf("%d", &n); // input number of studens
if(n>0)
stu = malloc(n*sizeof(int)); // allocate memory
else
return 0;
for(index=0;index<n;index++)
scanf("%d", &stu[index]);
char gen;
scanf("%c", &gen);
for(index=0; index<n; index++){
if(gen=='g' && index%2!=0) {
sum += stu[index];
printf("%d", sum);
} else if(gen=='b' && index%2==0) {
sum += stu[index];
printf("%d", sum);
}
}
return 0;
}
i know , that my question is unusual behaviour for coding , but i just do it , to understand C language in deep , so i ask user to enter a string and i want to print this string character by character , before doing this , i save the string in memory , which it's address saved in 'x' , can i print this string character by character , by this way ?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc ,char *argv[20])
{
char x ;
strcpy(&x,argv[1]);
printf("%s and it's length is %d : \n" , &x , strlen(&x));
int i ;
for(i=0 ; i < strlen(&x) ; i++)
{
printf(" hi : %c\n" , x[i]);
/* also i try '%x[i]' but it's give me another error
so how i do this ??*/
}
return 0;
}
The basic idea is correct, but there are some problems in the code.
x is only a single character. You´ll need an array of it.
Then replace every &x with x, because the array pointer itself is already an address.
And another thing: char *argv[20].
Why 20? Why not char *argv[] ?
So, starting from the beginning:
int main(int argc ,char *argv[20])
^^^^
This does nothing; whenever you declare a function parameter as T a[N] or T a[], it's intepreted as T *a; the traditional way to write this is as either
int main( int argc, char *argv[] )
or
int main( int argc, char **argv )
The second case more accurately reflects what's really happening; argv is a pointer to a sequence of pointers to char. The value of argv[argc] is NULL.
{
char x ;
strcpy(&x,argv[1]);
This is a problem; by declaring x as char, you've only set aside enough storage to hold a single character value1, but you're trying to use it to store an array of character values; that isn't going to work, and you're going to wind up clobbering whatever memory immediately follows x, which may or may not lead to a crash. C doesn't do any bounds checking for you; when you give strcpy an address, it will happily copy the given string to the storage following that address without making sure that storage is valid.
You have two options at this point: you can either declare x as an array of char:
char x[SOME_SIZE]; // where SOME_SIZE is large enough to handle your
// largest expected input
and use strcpy as follows:
strcpy( x, argv[1] );
or you can simply declare x as a pointer to char:
char *x;
and assign it to point to the beginning of argv[1]:
x = argv[1];
Either way, the rest of the code becomes
printf("%s and it's length is %d : \n" , x , strlen(x)); // no & before x
int i ;
for(i=0 ; i < strlen(x) ; i++)
{
printf(" hi : %c\n" , x[i]);
}
return 0;
}
Note that a much simpler way of doing this would be
int main( int argc, char **argv )
{
char *p = argv[1];
if ( p ) // argv[1] is not NULL
{
while ( *p ) // argv[1][i] is not 0
printf( "hi: %c\n", *p++ );
}
return 0;
}
1. Which is why x[i] wasn't working for you, since x is not an array or pointer expression
deviantfan is right that you are overwriting something in memory that does not belong to the variable. Here is one of the ways to accomplish your task without any memory-editing voodoo:
#define ARGV_SIZE 20
int main(int argc ,char *argv[ARGV_SIZE])
{
char x[ARGV_SIZE];
int argvLength;
strcpy(x, argv[1]);
argvLength = strlen(x);
printf("%s and it's length is %d : \n" , x , argvLength);
for (int i = 0 ; i < argvLength; i++)
{
printf(" hi : %c\n" , x[i]);
}
return 0;
}
or without the x variable you can do this:
int main(int argc ,char *argv[])
{
int argvLength = strlen(argv[1]);
printf("%s and it's length is %d : \n" , argv[1] , argvLength);
for (int i = 0 ; i < argvLength; i++)
{
printf(" hi : %c\n" , argv[1][i]);
}
return 0;
}
try this
#include<stdio.h>
#include<string.h>
int main(int argc ,char *argv[20]){
char y = 'Y';
char x ;
char z = 'Z';
strcpy(&x, "This program is correct!!!");
printf("%s and it's length is %d : \n" , &x , strlen(&x));
printf("%c%c%c", x,y,z);//print TYZ ?
return 0;
}
Am trying to read a file which contains the coordinate values for my code. each time i use scanf it reads only the first line...(60,70,200,200). my question is how do i make my code read all the contents of my file and print it out on the screen.here is my code and file.
FILE.txt:
S (60,70)(200,200)
S (30,40)(100,200)
S (10,20)(80,10)
S (60,400)(700,200)
S (160,70)(240,20)
MY CODE:
#include <stdio.h>
int a;
int b;
int c;
int d;
int data[4][5];
int main ( int argc, char *argv[] )
{
if ( argc != 2 ) /* argc should be 2 for correct execution */
{
/* We print argv[0] assuming it is the program name */
printf( "usage: %s filename", argv[0] );
}
else
{
// We assume argv[1] is a filename to open
FILE *file = fopen( argv[1], "r" );
/* fopen returns 0, the NULL pointer, on failure */
if ( file == 0 )
{
printf( "Could not open file\n" );
}
else
{
int i,j;
for (j=0; j < 5; j++)
{
for (i=0; i < 4; i++) {
fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d);
data[i][j] = (a, b, c, d);
printf("%d,%d,%d,%d\n",a, b, c, d);
}
}
fclose( file );
}
}
}
You must check the return value of I/O calls such as fscanf(). If it's failing, it will return 0 without changing your variables.
Also, this:
data[i][j] = (a, b, c, d);
Doesn't make a lot of sense in C. Remember that C doesn't have tuples like Python. The above is equivalent to:
data[i][j] = d;
Use while loop:
const int NumberOfValuesIamGoingToReadAtOnce = 4;
while (fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d) == NumberOfValuesIamGoingToReadAtOnce)
{
// do some actions with obtained values
}
as fscanf returns number of read values by return value you can judge if EOF achieved or file wrongly written
Try reading the newline as well:
fscanf(file, "S (%d,%d)(%d,%d)\n", &a, &b, &c, &d);
But why the double loop: you're already reading 4 values at the same time.
Instead, make it one infinite loop and check whether you've read 4 values; break when you did not read 4 values.
Lastly:
data[i][j] = (a, b, c, d);
does not make any sense (as any decent compiler warning will tell you). This, instead, may be where you want your second loop: around the assignement, not the scanf statement.
declar data[4][5] to data[5][4]
modify the loop
for (i=0; i < 5; i++)
{
fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d);
data[i][0] =a;
data[i][1] =b;
data[i][2] =c;
data[i][3] =d;
printf("%d,%d,%d,%d\n",a, b, c, d);
}
If you are going to fscanf(), you have to careful as you have to make sure the file is in correct format with exact number of spaces like how read in fscanf().
I would recommend using fgets() then reading numbers from the string using sscanf().
data[i][j] = (a, b, c, d);
This line doesn't do what you think it does. You really don't need another loop as you read all numbers in a line at once.
for (j=0; j < 5; j++)
{
fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d);
data[j][0] = a;
data[j][1] = b;
data[j][2] = c;
data[j][3] = d;
printf("%d,%d,%d,%d\n",a, b, c, d);
}
}
And change data[4][5] to data[5][4];
I used fgets to read file line per line and I used sscanf instead of fscanf
#include <stdio.h>
#include <string.h>
int data[4][5];
char line[128];
int main ( int argc, char *argv[] )
{
if ( argc != 2 ) /* argc should be 2 for correct execution */
{
/* We print argv[0] assuming it is the program name */
printf( "usage: %s filename", argv[0] );
}
else
{
// We assume argv[1] is a filename to open
FILE *file = fopen( argv[1], "r" );
/* fopen returns 0, the NULL pointer, on failure */
if ( file == 0 )
{
printf( "Could not open file\n" );
}
else
{
int i=0;
line[0] = 0;
while(fgets(line,sizeof(line),file))
{
sscanf(line, "S (%d,%d)(%d,%d)", &data[i][0], &data[i][1], &data[i][2], &data[i][3]);
printf("%d,%d,%d,%d\n", data[i][0], data[i][1], data[i][2], data[i][3]);
i++;
}
fclose( file );
}
}
}
I need to make a program that accepts no less than 2 and no more than 6 arguments at the command line and then prints out the 1st or 2nd character
EX: asdf asdf asdf asdf
prints out as: a s a s
I have the initial array setup and working, the for loops below are meant to cut the string off at a space in the input and copy it to a new string, but it is not working correctly. I am new to C, and to this site. Any help is greatly appreciated.
#include <stdio.h>
#include <string.h>
int main(){
char a[50];
char b[50];
char c[50];
char d[50];
char e[50];
char f[50];
int i;
printf("enter a string (Ex: asdf asdf asdf... Must have atleast 2 arguments but no more than six): ");
scanf("%s", a);
printf("%c", a);
for (i = 0; i != 50; i++){
if(a[i]==' '){
char strncpy(b, &a[i], i+2);
printf("\n%c ",a[1]);
printf("%c ",b[0]);
}
}
for (i = 0; i != 50; i++){
if(b[i]==' '){
char strncpy(c, &b[i], i+2);
printf("%c ",c[1]);
}
}
for (i = 0; i != 50; i++){
if(c[i]==' '){
char strncpy(d, &c[i], i+2);
printf("%c ",d[0]);
}
}
for (i = 0; i != 50; i++){
if(d[i]==' '){
char strncpy(e, &d[i], i+2);
printf("%c ",e[1]);
}
}
for (i = 0; i != 50; i++){
if(e[i]==' '){
char strncpy(f, &e[i], i+2);
printf("%c ",f[0]);
}
}
return 0;
}
You don't need to copy your strings out of anywhere... Coming from the command line you'll have them sitting in argv:
int main( int argc, char **argv )
{
}
Where argc is the total number of arguments plus 1 (the first is the name that invoked your program), and argv is an array of pointers to each argument string. These have already been tokenised from the command-line.
So first you wanna test you have enough arguments. I like to explicitly make a new variable to remove the off-by-one confusion from comparisons:
int nparams = argc - 1;
if( nparams < 2 || nparams > 6 ) {
printf( "Wrong number of arguments\n" );
return -1;
}
Then you loop over your arguments. The first will be in position 1 of the array... From your example, it seems that you print the first character of the first argument, and the second character of the next, then continue alternating. That's a modulo operation. I have a variable which that chooses which character to print.
int i, which;
for( i = 1; i <= nparams; i++ ) {
which = (i-1) % 2;
printf( "%c\n", argv[i][which] );
}
This does assume that every second argument is at least two characters long. No error checking. If you need error checking, you need to make sure that the character you're printing is not the string-terminator (value 0). In the case of the second character, you also need to check the value before it is not 0. I don't know if it's possible to specify an argument that is a string of zero length. Perhaps a reader who does know can comment.
Well, I may as well put it in... So your loop would look a little like this:
if( argv[i][0] == 0 || argv[i][which] == 0 ) {
printf( "\n" );
} else {
printf( "%c\n", argv[i][which] );
}