parse integer without appending char in C - c

I want to parse an integer but my following code also accepts Strings like "3b" which start as a number but have appended chars. How do I reject such Strings?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int n;
if(argc==2 && sscanf(argv[1], "%d", &n)==1 && n>0){
f(n);
return 0;
}
else{
exit(EXIT_FAILURE);
}
}

For your problem, you can use strtol() function from the #include <stdlib.h> library.
How to use strtol(Sample code from tutorial points)
#include <stdio.h>
#include <stdlib.h>
int main(){
char str[30] = "2030300 This is test";
char *ptr;
long ret;
ret = strtol(str, &ptr, 10);
printf("The number(unsigned long integer) is %ld\n", ret);
printf("String part is |%s|", ptr);
return(0);
}
Inside the strtol, it scans str, stores the words in a pointer, then the base of the number being converted. If the base is between 2 and 36, it is used as the radix of the number. But I recommend putting zero where the 10 is so it will automatically pick the right number. The rest is stored in ret.

The ctype.h library provides you the function isdigit(char) function that returns whether the char provided as argument is a digit or not.
You could iterate over argv[1] and check it this way.

Related

c - how can I print specified count of a char in a line

I want to print a line similar as following:
====================================
And I need to control the count of the char, and able to specify which char to print.
I don't want to use loop.
Is it possible to do this with a single printf() statement?
#Update
I ask this because I use printf in this way sometimes:
printf("%10s\n", "abc");
So, if printf could do this, then it's possible to do what I ask, I am just not sure ... now I know it can't ...
Ok, I wrote a simple util function to do this:
#include <stdio.h>
void printRepeatChar(char c, int count) {
char cs[count+1];
int i;
for(i=0; i<count; i++)
cs[i] = c;
cs[count] = '\0';
printf("%s\n", cs);
}
int main(int argc, char * argv[]) {
printRepeatChar('-', 6*4);
}
maybe use memset() from string.h instead of the direct loop makes the code shorter, just as in the answers.
And, thank you all for help.
#include <stdio.h>
#include <string.h>
void PrintStuff( char to_print, int length ) {
// adjust buffer size as desired
char buffer[256];
// -1 for null terminator
if( length > sizeof(buffer)-1 ) length = sizeof(buffer)-1;
// fill buffer with desired character
memset( buffer, to_print, length );
// add null terminator
buffer[length] = 0;
// print to output
puts( buffer );
}
int main() {
PrintStuff( '=', 11 );
return 0;
}
http://ideone.com/RjPr83
And to answer the subquestion: no, printf cannot repeat a character as a formatting rule. It can only repeat spaces or 0's when padding.
#include <stdio.h>
#include <string.h>
int main(void) {
char c='=';
char a[20];
memset(a,c,(sizeof(a)-1));
a[19] = '\0';
printf("%s\n",a);
return 0;
}
Dynamic memory allocation and character scanning can be added to this .

Concatenating an int to a string or converting in C

Im looking for a 6 digit random number on the end of foo-, I have been trying for a few hours now with no success. only error messages
note: expected 'char *' but argument is of type 'int'
Ive tried to convert the int to char but it just doesn't like it, My code is below,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
char* concat(char *s1, char *s2)
{
char *result = malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator
//in real code you would check for errors in malloc here
strcpy(result, s1);
strcat(result, s2);
return result;
}
int main ()
{
srand(time(NULL));
int r = rand();
printf(concat("foo-", r));
return 0;
}
You could do this
printf("foo-%d", r);
or
char buffer[10];
sprintf(buffer, "%d", r);
char *c = concat("foo-", r);
printf("%s", c);
free(c);
This will use your function. Please read the manual pages for sprintf and printf
for example:
srand(time(NULL));
int r = rand();
char* str = (char*)malloc(sizeof(char)*20);
snprintf(str, 7, "%d", r);
if (strlen(str) < 6) { /* if r had less than 6 digits */
sprintf(str, "%06d", r);
}
char* s = concat("foo-", str);
printf("%s",s);
free(str);
free(s);
return 0;
from http://joequery.me/code/snprintf-c/ :
int snprintf(char *str, size_t size, const char *format, ...);
str is the buffer where printf output will be redirected to. size is the maximum number of bytes(characters) that will be written to the
buffer, including the terminating null character that snprintf
automatically places for you. The format and the optional ...
arguments are just the string formats like "%d", myint as seen in
printf.
so, in order to get a 6 digit number converted, you specify in snprintf() the size argument to 7 (you include a null character).
sprintf() function sends formatted output to a string pointed to by the first argument (in our case this is str). %06d format provides that to str at least 6 digits will be sent.
CONCLUSION
you want to convert a 6 digit number to a char array. if the number had at least 6 digits, with snprintf() you will get the first 6 digits of the number that was converted. if it has less than 6 digits, the sprintf() will add zeroes at the beginning until there are 6 digits. so, if r = 101; the result would be 000101.
note that with your usage of concat function:
printf(concat("foo-",r));
compiler warns about (gcc in my case):
warning: format not a string literal and no format arguments
[-Wformat-security]
printf() function needs to know the format of the string argument that is passed. there's a nice answer about it right here : warning: format not a string literal and no format arguments
In the example I'm using sprintf to convert int to char[]. Also I'm using modulo operation to ensure the result will have no more than 6 digits. The %06d argument for sprintf will ensure that the result will have no less than 6 digits.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
char buf[7] = { 0 };
int r;
srand(time(NULL));
r = rand() % 1000000;
sprintf(buf, "%06d", r);
printf("foo-%s\n", buf);
return 0;
}
Your problem occurs when you attempt to call concat with the int value r as the second argument. Notice your definition of concat:
char* concat(char *s1, char *s2);
The second argument is char *s2. In your program you attempt to call it with:
int r = rand();
printf(concat("foo-", r));
r is an integer. Try this to correct the problem:
int main ()
{
srand(time(NULL));
int r = rand();
char str[] = "bar";
printf(concat("foo-", str));
return 0;
}

Getting integer while using strtok() in string

I'm new to C and need your help.
I'm trying to get an integer from a string that has a number in it.
I have with me a code I did but the only problem is when I'm assigning years as int i think I'm getting some sort of an address. Is there a way to get my char years into an in years?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char sentence[]="trade_#_2009_#_invest_#_DEALING";
char *word=strtok(sentence, "_#_");
char *year=strtok(NULL,"_#_"); // assigning NULL for previousely where it left off
char *definition=strtok(NULL,"_#_");
char *synonyms=strtok(NULL,"_#_");
printf("%s\n", word);
printf("%s\n", year);
printf("%s\n", definition);
printf("%s\n", synonyms);
return 0;
}
int iYear = 0;
sscanf(year,"%d",&iYear);
This should be the simplest.
You might also want to look at atoi function.
Use strtol or strtoul.
Here's an example taken from the strtol page that I linked to above:
/* strtol example */
#include <stdio.h> /* printf */
#include <stdlib.h> /* strtol */
int main ()
{
char szNumbers[] = "2001 60c0c0 -1101110100110100100000 0x6fffff";
char * pEnd;
long int li1, li2, li3, li4;
li1 = strtol (szNumbers,&pEnd,10);
li2 = strtol (pEnd,&pEnd,16);
li3 = strtol (pEnd,&pEnd,2);
li4 = strtol (pEnd,NULL,0);
printf ("The decimal equivalents are: %ld, %ld, %ld and %ld.\n", li1, li2, li3, li4);
return 0;
}

In C: I want to take a mix of characters and convert them to lower case

Why does my code not accept the argv[] string? What do I need to do to fix it? I want to be able to type in both lower and upper case letters and end up with only lowercase letters in the array. Thanks for any help.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char argv[])
{
char word[30]= atoi(argv[1]); // here is the input
for (int i = 0; word[i]; i++)
word[i] = tolower(word[i]);
printf("Here is the new word: %s\n", word);
return 0;
}
int main(int argc, char argv[])
should be:
int main(int argc, char *argv[])
Besides, strtol is a better option than atoi as strtol can handle failures better.
You have several problems with your code:
As KingsIndian already mentioned, you are missing a * in front of the argv paramter of the main function. This 'Main Function' wiki page contains some more details on this.
atoi is used to convert a string number to an integer number. This is not what you want I suppose. argv[x] is already a string (char *), so you can use it directly.
If you use it directly, you cannot modify it contents (not allowed, I believe). Therefore you need to make a copy. Use strlen() to find out the length of argv[1], malloc() to create an buffer and strcpy() to copy it:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *word = malloc(strlen(argv[1]) + 1);
strcpy(word, argv[1]);
int i;
for (i = 0; word[i]; i++)
word[i] = tolower(word[i]);
printf("Here is the new word: %s\n", word);
return 0;
}
Additional notes:
It would be better (more robust) if you check the amount of given command line parameters using argc!
In theory malloc() can return 0, indicating that claiming the memory did fail. So you should check for this.
If you only want to print the lower case world, you do not require to first convert it and then print it. Instead, you could directly print each converted character.

function to read a string and get the length - C

I'm having issues writing a C function that reads a string from STDIN, and returns the length of said string... Suggestions?
So, simply use strlen from the C standard library:
#include <string.h>
So the strlen() function is available. You just need to pass a char pointer, and it will return the string length:
size_t length = strlen( myStr );
Note that size_t is an integral type.
By the way, if you don't know about this function, you should really dig into the C library, and lear about the basic functions it provides.
#include <stdio.h>
#include <stdlib.h> // not totally necessary just for EXIT_SUCCESS
#include <string.h>
int main(int argc, char* argv[]) {
// check number of params
if (argc != 2) {
// argv[0] is name of exe
printf("usage: %s string", argv[0]);
// check length of first command line parameter
} else {
// strlen does the counting work for you
unsigned int length = strlen(argv[1]);
printf("Length is %d\n", length);
}
return EXIT_SUCCESS;
}

Resources