Is there a strtol() or sscanf() equivalent where you can specify the no. of chars to convert?
I have a use case where I need to convert sub sections of an array of chars to ints, so I don't have the terminating null char present
In other words, I'd like the equivalent of strncmp() in relation to strcmp()
i.e. strntol() or snscanf() but they don't seem to exist
I imagine i'll just have to copy and append a '\0' and use strtol() or sscanf() but just wanted to check I hadn't missed an existing function for this purpose
question is really do they exist? am i just searching for the wrong thing?
There is no equivalent for strtol, but you can use format specifier to limit the number of characters considered by sscanf:
char *str = "1234567890";
int n;
sscanf(&str[3], "%3d", &n);
printf("%d\n", n);
The %3d specifier instructs sscanf to take only three digits from str, while &str[3] tells sscanf to start at the index 3.
The above code prints 456 (demo).
Related
hello ive got this simple program, where i need to imput a number, and 2-letter string, the string is working normally, but the number gets weird
here is the program
void main(){
int input_year=0;
char input_string[1];
scanf("%d %s", &input_year, input_string);
char temp1 = input_string[0];
char temp2 = input_string[1];
printf("%d", input_year);
printf("%c", temp1);
printf("%c", temp2);
}
input used: 20200405 RD number (whitespace) String
the temp1 and temp2 are ok, and do what i expect them to do, but the input_year prints 20200192 rather than 20200405.
You need to remember that strings in C are really called null-terminated strings. A string of even one single character need space for two characters to fit the null-terminator.
Also remember that the size provided in array declarations is the actual number of elements, not the top index. So when you define input_string as an array of a single element, that means it only have a single element, with index 0.
If you want to read a string containing two characters you need to define an array of three characters: The two characters in the string plus the null-terminator.
You also need to limit the number of characters that scanf will read, so users can't input arbitrarily long strings and cause buffer overflows.
In short:
// Place for two characters, plus null-terminator
char input_string[3];
// Limit the input to only two characters (not including null-terminator)
scanf("%d %2s", &input_year, input_string);
On another note, if you want to use the date input in any other way than a single number, I recommend you read it as separate year, month and day:
unsigned year, month, day;
char input_string[3];
scanf("%4u%u%2u %2s", &year, &month, &day, input_string);
Also note that I use unsigned as a type (and the corresponding scanf format) as the input can't and shouldn't be negative.
You should also really check what scanf returns, to make sure the input is valid.
And lastly, to better handle input validation, I recommend you use fgets to read the input into a large string. Then use e.g. sscanf (with checking return values) to attempt to parse the input.
Your input buffer is too small
char input_string[1];
That reserves space for one character. You need 3 in your case of 'rd'. The extra one is because c always adds a 0 at the end of a string. So you need
char input_string[3];
at least if you are sure its always 2 characters
Or maybe
char input_string[10];
if it could be larger. You can tell sprintf the max size you will accept like this (say 2 in your case)
scanf("%d %2s", &input_year, input_string);
-----------^
I'm new to this, and I'm assuming there is an easy solution to my issue. My first formula works exactly how I'd like it to. If the user input matches dogage99, then it prints "Correct". I want to do something similar, but using words instead of numbers. I've switched double for char, and adjusted the formula accordingly.
The problem is, the second formula doesn't work as I expected. When the user input matches dogname1, it doesn't print "Correct", it just continuously asks to "enter dog name".
What can I do to fix my issue?
int main()
{
double guess99;
double dogage99 = 3;
while (guess99 != dogage99) {
printf ("enter dog age:");
scanf ("%lf", &guess99);
}
printf ("Correct\n");
char guess1;
char dogname1= "spot";
while (guess1 != dogname1) {
printf ("enter dog name:");
scanf ("%s", &dogname1);
}
printf ("Correct\n");
First of all the line
char dogname1= "spot";
should be corrected to
char *dogname1= "spot";
This way the char array dogname1 will be correctly initialized as a character array and will contain the null-terminator "\0" at the end of the array.
You must also ensure, that guess has enough memory secured, so you must either create a array of sufficiently enough bytes (for e.g. 256), or dynamically allocate memory. In this example I would do the first changing char guess1; to char guess1[256];
Knowing that guess1 has sufficiently enough memory and a null-terminator we can next rewrite the while loop to
while(strcmp(guess1, dogname1)) { ... }
The strcmp() standard library function returns 0 if and only if both character arrays match lexicographical and that is also the time we want to go out of the loop. It is also important to know, that you must ensure both arrays have null-terminators when using this exact function. If you cannot ensure it, then use strncmp().
For reference about all the different compare functions and their implications: https://www.ibm.com/docs/en/aix/7.1?topic=s-strcmp-strncmp-strcasecmp-strcasecmp-l-strncasecmp-strncasecmp-l-strcoll-strcoll-l-subroutine
I am sure the compiler is complaining big time at you about
char dogname = "spot";
in c the type char represent a single character not a string. Strings in C are a sequnce of characters followed by a char set to \0. The compiler will set that up for you if you do
char *dogname="spot";
It will allocate 5 bytes , load s,p,o,t,\0 into those bytes and set the dogname variable to point at the first character.
If you want to compare string you have to use the c library function called strcmp - https://man7.org/linux/man-pages/man3/strcmp.3.html.
Alos you need a char array to receive the input. We just say we want 50 characters. Must also tell scanf to not allow more than 50 charaters. Note that I asked for 51 character array to allow for the trailing 0 that must always be present.
so your loop becomes
char guess1[51];
char *dogname1= "spot";
while (guess1 != dogname1) {
printf ("enter dog name:");
scanf ("%50s", guess1);
}
printf ("Correct\n");
note you must #include string.h
check this out https://www.tutorialspoint.com/cprogramming/c_strings.htm
I'm trying to read the characters of a character array by number in c. I've stripped the program down to isolate the problem. I know this is about my misunderstanding of how arrays and memory works and I am ready to be called clueless but I would like to know what I am misunderstanding here. Here is what I have:
#include <stdio.h>
int main(int argc, char **argv) {
char buffer[] = "stuff";
printf("buffer is %s\n", buffer);
printf("first character of buffer is %s", (char)buffer[0]);
return 0;
}
You have to write the correct format specifier. Now you used %s ...what happens?
It looks for an string which is null terminated. But it doesn't find one. So it simply cant put anything in the output . That's it.
Use %c instead.
In C there is a very big difference between a character and a string.
A character is simply a number in a range of 256 different options.
A string is not really a type of its own, it is merely an array of chars (which, in C, is simply evaluated as a pointer to the first character of the string).
Now, when you type buffer[0], this is evaluated to the value at the beginning of the string (first value in the array). Indeed, this is of char type (and therefore you do not need the (char) casting, because this will not do anything in the case of your code).
What you need is to tell printf() how to evaluate the input that you give it. %s is for a string (an array of chars). But note and remember that buffer[0] is not an array of chars, but rather a char.
So you actually want to use %c, instead of %s. This tells printf() to evaluate the parameter as a char type.
What your code currently does is take the value buffer[0] (which is just a number) and consider it as a pointer to a location in memory where a string is kept, and printf() tries to print this string. But this memory location is simply invalid. It is not a location you've accessed before.
In conclusion you want:
printf("first character of buffer is %c", (char)buffer[0]);
or even simpler:
printf("first character of buffer is %c", buffer[0]);
For other specifiers of the printf() function, look here:
http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm
If you want to print only a single char use %c format.
printf("first character of buffer is %c\n", (char)buffer[0]);
what I'm trying to do is to send a string over the network. the point is that the server which receives the string must make the sum of all the numbers and send it back. so i think the easiest way is to take the string and put it in a float array (it does not matter if ints get in there aswell, since the final sum will be a float number).
unfortunately i have no idea how to do that, or more exactly, how to approach it. how do i take the numbers 1 by 1 from a string (let's say, each number is separated by a space)? there must be some function but i can't find it.
the language is plain C under unix.
Use strtod() to convert the first number in the string to double. Add that to your sum, then use the endptr return value argument to figure out if you need to convert another, and if so from where. Iterate until the entire string has been processed.
The prototype for strtod() is:
double strtod(const char *nptr, char **endptr);
Also note that you can run into precision issues when treating integers as floating-point.
You can use fscanf to read from a stream, just like you would use scanf to read from stdin.
You can use strtok to split your string and atof to convert it to float.
char* p;
float farr[100];
int i = 0;
//str is your incoming string
p = strtok(str," ");
while (p != NULL)
{
farr[i] = atof(p);
p = strtok(NULL, " ");
}
I just ran it in an online compiler - http://ideone.com/b3PNTr
you can use sscanf() to read the formatted input from a string.
you can use something like
string=strtok(input," ")
while(string!=NULL)
{ sscanf(string,"%f",&a[i]);
i++;
string=strtok(NULL," ");
}
inside a loop. you can use even atof() instead of using sscanf() with %f.
I am trying to copy the memory value of int into the char buffer. The code looks like below,
#define CPYINT(a, b) memcpy(a, &b, 4)
............
char str1[4];
int i = 1;
CPYINT(str1, i);
printf("%s",s);
...........
When I print str1 it’s blank. Please clarify.
You are copying the byte representation of an integer into a char array. You then ask printf to interpret this array as a null terminating string : str1[0] being zero, you are essentially printing an empty string (I'm skipping the endianness talk here).
What did you expect ? Obviously, if you wanted to print a textual representation of the integer i, you should use printf("%d", i).
try
printf("%02X %02X %02X %02X\n", str1[0], str1[1], str1[2], str1[3]);
instead.
The binary representation of the integer 1, probably contains leading NULs, and so your current printf statement terminates earlier than you want.
What is your intention here? Right now you are putting arbitrary byte values into the char array, but then interpreting them as a string, as it happens the first byte is probably a zero (null) and hence your print nothing, but in all probability many of the characters will be unprintable, so printf is the wrong tool to use to check if the copy worked.
So, either: loop through the array and print the numeric value of each byte, %0xd might be useful for that or if your intention is actually to create a string representation of the int then you'll need a larger buffer, and space for a null terminator.
Maybe you need convert intger to char* in that way tou can use itoa function
link text