I'm trying to understand a line of code in a problem set provided by CS50. Herein lies the issue:
can a number both be simultaneously a string an an integer? Isn't a string traditionally considered to be a string of letters (i.e a word etc? or a paragraph)?
if a number can be both a string and an integer, what is the use of differentiating it? Particularly in the line of code below.
#include <cs50.h>
#include <stdio.h>
int get_positive_int(string prompt);
int main(void)
{
int i = get_positive_int("Positive Integer: ");
printf("%i\n", i);
}
// Prompt user for positive integer
int get_positive_int (string prompt)
{
int n;
do
{
n = get_int("%s", prompt);
}
while (n <0 || n > 8);
return n;
}
"No!" a variable can't have multiple data types. This may be possible but only with the representation context. For Example:
String a= "1";
Int b=1;
1)We can print both variables and both will give us the same output.
2)We can perform calculations on the second one but to perform calculations on the string, you may need to convert it into number format - either int, double or float.
I saw your follow up question. The difference between these two functions is clear with my second point. You have to pass a string value to the function int get_positive_int(string prompt). But in the case of int get_positive_int(int prompt), you may have to pass an integer value to this function. Both these functions will return an integer value. It depends what you are doing inside the function.
For the function int get_positive_integer(string prompt), you may get a string from the user and convert it into an integer, then return that integer value.
The answer to your question is "no". A number can have one of several C types (e.g. int, double, ...), but only one of them, and string is not a numeric type.
I'm not sure what's unclear to you about the code.
Related
I got input like 12345679890 but I just want to read 1 integer at a time, that is read 1 then 2 then 3 ... and do some operations next. However when I use scanf, it read all the numbers i.e. 1234567890. Can anyone help? Thank you!!
This is the code that I have
#include <stdio.h>
int main() {
int input;
scanf("%x",&input);
while (scanf("%x",&input)==1){}
}
12345679890 is an integer, what you want to do is read one digit at a time. To do this, you would use the format string %1u rather than %x.
For a start, %x specifies a hexadecimal item, meaning it will accept a through f as well, and %d would allow for a leading sign which you probably don't want.
In addition, you appear to consume (and throw away) the first digit before you enter the loop, so you would be better off with something like:
#include <stdio.h>
int main(void) {
unsigned int digit;
while (scanf("%1d", &digit) == 1) {
//doSomethingWith(digit);
}
return 0;
}
I wrote a program to fetch all the phone numbers from a file which has other text like at commands and other error from other child process. Here when I try to convert the string to integer using a user-defined function I facing the problem. The converted value stored in the function is not properly returned to main program, instead its returning some unusual and it seems to be the same for every execution. Its surprising me. Can someone advice me.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char lic[128];
unsigned long long sum=0ULL;
unsigned long long stringtoint(char str[])
{
int i=0;
sum=0;
if(str[strlen(str)]!='\0')
return -1;
//puts("Im in function");
while(str[i]!='\0'){
//printf("- %c -\n",str[i]);
if(str[i] >= 48 && str[i] <= 57){
sum = sum*10 + (str[i] - 48);
//printf("%c and %llu\n",str[i],sum);
}
i++;
}
if(sum>0)
printf("\nIn function passed string is %s and integer value is %llu\n",str,sum);
return sum;
}
FILE *file;
int main(){
//long long int inte;
int64_t inte; file = fopen("receive","r");
if(file!=NULL)
while(fscanf(file,"%s",lic)!=EOF){
inte = 0;
inte=stringtoint(lic);
if(inte !=0){
printf("In Main %llu is the value of the string %s",inte,lic);
if(inte==sum)
printf("\n%llu and %llu are same\n",inte,sum);
}
}
printf("\n");
fclose(file);
return 0;
}
The result I was getting for this program was given below.
In function passed string is 8939095683 and integer value is 8939095683
In Main 349161091 is the value of the string 8939095683
shameerariff#shameerariff-Satellite-L450:~/Workinffolder/ivr/IVRReporting$ ./datadecoder
In function passed string is 8939095683 and integer value is 8939095683
In Main 349161091 is the value of the string 8939095683
shameerariff#shameerariff-Satellite-L450:~/Workinffolder/ivr/IVRReporting$ ./datadecoder
In function passed string is 8939095683 and integer value is 8939095683
In Main 349161091 is the value of the string 8939095683
Your valuable advice are needed, Thank you in advance for your support.
Point 1. You need to change
int stringtoint(char str[])
to
unsigned long long stringtoint(char str[])
Point 2. %lld is not the correct format specifier for unsigned long long. Use %llu
Can someone advice me.
Yes. Don't write your own function, but use the atoi function available in the C standard library if you really want to operate on char arrays, or use the stoi function to work on std::string, or use any C++ iostream to read ints from your strings. With the latter, you can basically just use the file stream you can directly get when opening a ifstream with C++'s standard library.
EDIT: I should mention you shouldn't use atoi/stoi, but atoll/stroul to actually reflect the fact that your numbers could be bigger than whatint can hold.
Also, phone numbers are not integers. In many countries, city area codes start with 0, which you can't represent in any numeric type. In fact, telephone numbers are not numbers, but sequences of digits, if you ask me.
The goal of this program is to create a function which reads in a single string, user typed, command (ultimately for program to be used in conjunction with a robot) which consists of an unknown command word(stored and printed as command), and an unknown number of decimal parameters(the quantity is stored and printed as num, and the parameters are to be stored as float values in the array params). In the User input, the command and parameters will be separated by spaces. I believe my issue is with the atof function when I go to extract the decimal values from the string. What am I doing wrong? Thank you for the help!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func(char *input, char *command, int *num, float *params);
int main()
{
char input[40]={};
char command[40]={};
int num;
float params[10];
printf("Please enter your command: ");
gets(input);
func(input,command,&num,params);
printf("\n\nInput: %s",input);
printf("\nCommand: %s",command);
printf("\n# of parameters: %d",num);
printf("\nParameters: %f\n\n",params);
return 0;
}
void func(char *input, char *command, int *num, float *params)
{
int i=0, k=0, j=0, l=0;
int n=0;
while(input[i]!=32)
{
command[i]=input[i];
i++;
}
for (k=0; k<40;k++)
{
if ((input[k]==32)&&(input[k-1]!=32))
{
n++;
}
}
*num=n;
while (j<n)
{
for (l=0;l<40;l++)
{
if((input[l-1]==32)&&(input[l]!=32))
{
params[j]=atof(input[l]);
j++;
}
}
}
}
A Sample Output Screen:
Please enter your command: Move 10 -10
Input: Move 10 -10
Command: Move
# of parameters: 2
Parameters: 0.000000
The Parameters output should, ideally, read "10 -10" for the output. Thanks!
Change atof(input[l]) to atof(input + l). input[l] is single char but you want to get substring from l position. See also strtod() function.
Other people have already remarked the problem in your code, but may I suggest that you have a look at strtod() instead?
While both atof() and strtod() discard spaces at the start for you (so you don't need to do it manually), strtod() will point you to the end of the number, so that you know where to continue:
while(j < MAX_PARAMS) // avoid a buffer overflow via this check
{
params[j] = strtod(ptr, &end); // `end` is where your number ends
if(ptr == end) // if end == ptr, input wasn't a number (say, if there are none left)
break;
// input was a number, so ...
ptr = end; // continue at end for next iteration
j++; // increment number of params
}
Do note that the above solution does not differentiate between invalid arguments (say, foo instead of 3.5) and missing ones (because we've hit the last argument). You can check for that by doing this: if(!str[strspn(str, " \t\v\r\n\f")]) --- this checks if we're at the end of string (but allowing trailing whitespace). See the second side-note for what it does.
SIDE-NOTES:
You can use ' ' instead of 32 to check for space; this has two advantages:
It is clearer to the reader (it's very clear that it's a whitespace, instead of "some magic number that happens to have meaning")
It works in non-ASCII encodings (and the standard allows other encodings, though ASCII is by far the most popular; one common encoding is EBCDIC)
For future reference, this trick can help you skip whitespace: ptr += strspn(ptr, " \t\v\r\n\f");. strspn returns the number of characters at the start of the string that match the set (in this case, one of " \t\v\r\n"). Check documentation for more info.
Example for strspn: strspn("abbcbaa", "ab"); returns 3 because you have aab (which match) before c (which doesn't).
you are trying to convert a char into a float,
params[j]=atof(input[l]);
you should get the entire word(substring) of the float.
Example, "12.01" a null terminated string with 5 characters and pass it to atof, atof("12.01") and it will return a double of 12.01.
so, you should first extract the string for each float parameter and pass it to atof
Avoid comparing character to ascii value, rather you could have use ' ' (space) directly.
Instead of using for loop with a fixed size, you can use strlen() or strnlen() to find the length of the input string.
I am Just a begineer in C Programming. While solving a programming assignement I came across the need to convert an array of unsigned char to integer.
For Example:
unsigned char x[]="567";
unsigned char y[]="94";
Now I have to add the integer values in both x and y. That is:
int sum=661;
What is the simplest way to do this?
You're looking for atoi() .
You have at least two options if you use standard library. The first is atoi() function from stdlib.h and second is sscanf()function from stdio.h.
Here are examples:
atoi()
char number_string[] = "47";
int number;
number = atoi(number_string);
sscanf()
char number_string[] = "47";
int number;
int return;
return = sscanf(number_string, "%d", &number);
/* it would be good idea to check the return value here */
sscanf() gives you a better error handling. Return value of sscanf() determines how many items were succesfully read (how many variables were filled). If there was an input failure, EOF is returned.
atoi() returns 0 if no valid conversion could be performed.
I don't understand the results of the following C code.
main()
{
char s[] = "AAA";
advanceString(s);
}
void advanceString(p[3])
{
int val = atoi(p);
printf("The atoi val is %d\n",val);
}
Here the atoi value is shown as 0, but I could not figure out the exact reason.
As per my understanding, it should be the summation of decimal equivalent of each values in the array? Please correct me if I am wrong.
atoi() converts a string representation of an integer into its value. It will not convert arbitrary characters into their decimal value. For instance:
int main(void)
{
const char *string="12345";
printf("The value of %s is %d\n", string, atoi(string));
return 0;
}
There's nothing in the standard C library that will convert "A" to 65 or "Z" to 90, you'd need to write that yourself, specifically for whatever charset you're expecting as input.
Now that you know what atoi() does, please don't use it to deal with numeric input in whatever you come up with. You really should deal with input not being what you expect. Hmm, what happens when I enter 65 instead of A? Teachers love to break things.
atoi() doesn't do any error checking whatsoever, which makes anything relying on it to convert arbitrary input fragile, at best. Instead, use strtol() (POSIX centric example):
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(void)
{
static const char *input ="123abc";
char *garbage = NULL;
long value = 0;
errno = 0;
value = strtol(input, &garbage, 0);
switch (errno) {
case ERANGE:
printf("The data could not be represented.\n");
return 1;
// host-specific (GNU/Linux in my case)
case EINVAL:
printf("Unsupported base / radix.\n");
return 1;
}
printf("The value is %ld, leftover garbage in the string is %s\n",
// Again, host-specific, avoid trying to print NULL.
value, garbage == NULL ? "N/A" : garbage);
return 0;
}
When run, this gives:
The value is 123, leftover garbage in
the string is abc
If you don't care about saving / examining the garbage, you can set the second argument to NULL. There is no need to free(garbage). Also note, if you pass 0 as the third argument, it's assumed the input is the desired value of a decimal, hex or octal representation. If you need a radix of 10, use 10 - it will fail if the input is not as you expect.
You'd also check the return value for the maximum and minimum value a long int can handle. However, if either are returned to indicate an error, errno is set. An exercise for the reader is to change *input from 123abc to abc123.
It's important to check the return, as your example shows what happens if you don't. AbcDeFg is not a string representation of an integer, and you need to deal with that in your function.
For your implementation, the most basic advice I can give you would be a series of switches, something like:
// signed, since a return value of 0 is acceptable (NULL), -1
// means failure
int ascii_to_ascii_val(const char *in)
{
switch(in) {
// 64 other cases before 'A'
case 'A':
return 65;
// keep going from here
default:
return -1; // failure
}
.. then just run that in a loop.
Or, pre-populate a dictionary that a lookup function could scope (better). You wouldn't need hashes, just a key -> value store since you know what it's going to contain in advance, where the standard ASCII characters are keys, and their corresponding identifiers are values.
It tries to convert the string into an integer. Since AAA cannot be converted into an integer the value is 0. Try giving it 42 or something.
If no valid conversion could be
performed, a zero value is returned.
See http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
Read atoi() as a to i (ASCII to integer).
atoi() converts a string representing a decimal number, to integer.
char s[] = "42";
int num = atoi(s); //The value of num is 42.
atoi expects its argument to be a string representation of a decimal (base-10) integer constant; AAA is not a valid decimal integer constant, so atoi returns 0 because it has no other way to indicate that the input is invalid.
Note that atoi will convert up to the first character that isn't part of a valid integer constant; in other words, "123" and "123w" will both be converted to 123.
Like everyone else is saying, don't use atoi; use strtol instead.