So I have managed to convert the string into an int. However, in code #1, when I try to assign it to the first slot in the array and print it out, it prints '<'. Why is it doing this? I know it has something to do with ascii characters. Code #2 prints out the int 60 which is what I want.
atoi(menuAttributes[c].c_str()) = 20;
quantity[d] = 3;
string price[14];
#1
price[0] = atoi(menuAttributes[c].c_str()) * quantity[d];
cout << price[0] << endl;
#2
cout << atoi(menuAttributes[c].c_str()) * quantity[d] << endl;
Pretty much, I want price[0] to equal the int 60, not the char '<'. Thanks!
EDIT: Solved, thanks for everyones help. Noob here, apologies!
it's because of your price definition:
string price[14];
- you have defined it as an array of 14 strings, and attempting to assign to the first string in the array (price[0]) a numerical value (which is bogus from string's point of view).
Once you define your price as int price[14], then you'll get what you expect
price needs to be defined as an integer array. When you try to store the integer value 60 in price, it's implicitly converted to (char)60, which is < on the ASCII table.
I have a little problem working on with char in C++ as I have tried comparing 2 texts in an if and there is what I've got:
Input:
if ( "bac" < "ab" ) cout<<"1";
if ( "ab" > "bac" ) cout<<"1";
Output :
11
I don't really understand why it is printing "11", but moreover if I erase the first 'if' it will no longer print anything on the screen. Could you please explain why it has such a behaviour on these IFs?
`if("abc" < "bcd" );
This is equivalent to:
char* a= "abc";
char* b ="bcd";
if( a < b );
a and b are pointers, addresses in memory. So no matter what are in the two strings, they are in different places in memory. That means no matter what the content of the two strings, a will never be equal to b.
When you "abc" you get the memory location of that string. So that is what is meant by, "You are comparing pointers."; C++ is not like other languages where the machine is abstracted away. You are working with the real one's and zero's that the machine uses. And everything lives somewhere in memory.
strcmp is a function that take two pointers then compares the values in the memory location that those pointers refer to.
if( ! strcmp(a,b) )
;//then the two strings are the same
You are comparing pointers, not characters.
If you're using a modern compiler you can do it like this instead:
if ("bac"s < "ab"s) cout << "1";
if ("ab"s > "bac"s) cout << "1";
The s suffix tells the compiler that the string literals are of type std::string.
If your compiler doesn't support that, you can do it the old fashioned way:
if (string("bac") < string("ab")) cout << "1";
if (string("ab") > string("bac")) cout << "1";
Or the ancient C-style way:
if (strcmp("bac, "ab") < 0) cout << "1";
if (strcmp("ab, "bac") > 0) cout << "1";
There is a part of a code for "making the first letter of each word capitalized" I dont understand.
http://www.cplusplus.com/forum/beginner/117463/
std::string str = x;
str [0] = toupper (str[0]);
std::for_each(str.begin()+1, str.end(), printChars);
std::cout << str;
return 0;
}
Void printChars(char& c)
{
if( (*(&c - sizeof(char))) == " ")
c = toupper(c);
}
I understand it sets the first letter to capital always, and checks for each one in the string after.
But why does he use if((*(&c - sizeof(char))) == " ") and how does the * , & and setting it to blank work in this case?
how does ... work in this case?
It does not work. The program that you show is ill-formed and is not likely to compile.
Void printChars(char& c)
There is no type Void in C++. I suspect that you intended to write void instead.
(some_char_value) == " " // expression simplified by me
You may not compare a character to a string literal.
But why does he use if((*(&c - sizeof(char))) == " ")
He doesn't. He uses if( (*(&c - sizeof(char))) == ' ').
how does the & work in this case?
It is the address-of operator. It is used here to get a temporary pointer to the memory address of c.
how does the * work in this case?
It is the indirection operator. It is used here to get the character at the memory location &c - 1. Which is a character in str right before the character referred to by c.
and setting it to blank work in this case?
He doesn't set anything in the quoted expression. == is the equality comparison operator. He compares the values of the &c - 1 and the character literal ' '.
In english: He tests whether the character before c is space. In other words: He test whether c is the first character of a word.
This code is performing simple pointer arithmetic. The code you are asking about is using the reference operator & to grab the address of the variable c. Then performing subtraction of the size of a char to check if the char before c is a space if so it calls toUpper(). So for example
if the address of c is 100 then &c - sizeof(char) is checking the char at address 99 then the * is used to dereference the variable which allows for the comparison of the variable using == " ".
I'm trying to concatenate two strings into a new one (finalString) like this:
finalString = string1 + '&' + string2
Firstly, I allocate the memory for finalString, then i use strcat().
finalString = new char[strlen(string1 ) + strlen(string2) + 2];
cout << finalString << endl;
finalString = strcat(finalString , string1 );
finalString = strcat(finalString , "&");
finalString = strcat(finalString , string2);
cout << finalString << endl;
I'll suppose that string1 is "Mixt" and string2 is "Supermarket".
The output looks like this:
═════════════════řřřř //(which has 21 characters)
═════════════════řřřřMixt&Supermarket
I know that if I use round brackets in "new char" the string will be initialized to 0 and I'll get the desired result, but my question is why does the first output has 21 characters, supposing that I allocated only 17. And even so, why does the final string length exceed the initial allocation size (21 > 17) ?
Thanks in advance!
Two words for you "buffer overrun"
The reason you have 21 characters initially is because there is a '/0' (also called null) character 22 characters away from the memory address that finalString points to. This may or may not be consistent based on what is in your memory.
As for the reason why you have a longer than what you wanted again you wrote outside the initial buffer into random memory. You did not crash because you did not write over something important.
strcat will take the memory address given, find the first '/0' it finds and from that place on it will copy the data from the second memory pointer you provide until the first '/0' it finds there.
What you are doing is VERY DANGEROUS, if you do not hit a /0' before you hit something vital you will cause a crash or at minimum bad behavior.
Undersand in C/C++ a char[] is just a pointer to the initial memory location of the first element. THERE ARE NO SAFEGUARDS! You alone must be careful with that..
if you set the first character of the finalString[0] = 0 then you the logic will work better.
As a different answer, why not use std::string:
std::string a, b, c;
a = "part1";
b = "part2";
c = a + " & " + b;
std::cout << c << '\n';
part1 & part2
Live example: http://ideone.com/pjqz9T
It will make your life easier! You should always look to use stl types with c++.
If you really do need a char * then at the end you can do c.c_str().
Your string is not initialized which leads to undefined behavior. In strcat, string will be appended when it finds the null character.
So, as others already mentioned, either you can do
finalString[0] = 0;
or in place of your first strcat use strcpy. This will copy the first string and put a null character at the end.
why 21 characters?
This is due to undefined behavior. It will keep on printing until it won't find a null or else it will crash as soon as it tries to access any illegal memory.
I don't understand how to use sscanf() in C++ for reading from a file.
I'm working on a program that reads three names of runners from a file, along with each of their five best times. I want to average out each runner's times and say who the best runner is. I am having the absolute hardest time with file IO.
Cplusplus.com has helped some, but doesn't really say how to read off, separate the char* (names) from the floats (times), etc. Elsewhere, I can't escape jargon and explanations that are too technical.
A friend showed me this code snippet to explain.
while(file>>str) {
sscanf (str.c_str(),"%d",&myint);
}
Anyone mind explaining to me how it's read?
Using sscanf() is considered a bit old school, but can be very beneficial and is worth mastering. I think you're looking for something like:
sscanf(input, "%s %f", name, &time);
where input is a line from the file. Some of the basics are %s for the basic string and %f for the float.
Enjoy the start of your programming; it only gets better as you gain experience.
scanf if the opposite of printf.
The first "s" in "sscanf" means it scans a string. "fscanf" scans a file, and "scanf" scans the standard input.
the formatting is the same as printf.
if sprintf(s, "%d x", 5) prints "5 x" into s than sscanf("5 x", "%d x", &n) will place 5 into n. It's allways the opposite of printf.
The exception is %s. %s in printf prints EVERY string. printf("%s", str); WILL print str, no matter what's in str. In scanf, %s is a word. A word is something without spaces. so reading a %s will only read a word.
sscanf(str, "%d", &a); means str has a format of "%d" (a single decimal number), and you are reaing this number to a (because &a is the second argument).
As an example
int a,b,c,d;
sscanf("10,20,30,40", "%d,%d,%d,%d", &a, &b, &c, &d);
will result in a = 10, b = 20, c= 30, d = 40. each %d will read to the next argument, and each will read a single decimal number.
Overall, the sscanf() function is used to convert a (C) string into a series of values in program variables under the guidance of a format string which describes the values to be found in the string.
Dissecting the quoted code:
while (file >> str)
{
sscanf(str.c_str(), "%d", &myint);
}
We can assume that file is an input stream and str is a string. The while loop reads one 'word' from the input into the string on each iteration, where a 'word' is a series of non-white space characters, possibly preceded by a series of white space characters.
The sscanf() statement in the example has three arguments and a return value which is ignored (rather at your peril). The first argument is a C style string, so the word that was read is converted to a C string with the str.c_str() call. The second argument is a format string which tells sscanf() what to expect in the string. In this case, the %d conversion specifier indicates a decimal integer. The third argument is a pointer to the corresponding type, where the converted value will be stored. In general, a format string can contain a number of conversion specifiers, and there needs to be one pointer argument for each conversion specifier that assigns (you can skip data by suppressing the assignment).
The return value from sscanf() is the number of successful assigning conversions. In this case, you should be checking that you got one conversion completed.
Here is a working miniature program based on your example:
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
static void read_stuff(std::istream &file)
{
std::string str;
while (file >> str)
{
std::cout << "IN: <<" << str << ">>" << std::endl;
int myint;
if (sscanf(str.c_str(), "%d", &myint) != 1)
{
std::cerr << "Oops: sscanf() failed" << std::endl;
std::exit(1);
}
std::cout << "GOT: " << myint << std::endl;
}
}
int main()
{
read_stuff(std::cin);
return(0);
}
Suppose you type the input line: 123 234 345 abc. Then the program produces:
IN: <<123>>
GOT: 123
IN: <<234>>
GOT: 234
IN: <<345>>
GOT: 345
IN: <<abc>>
Oops: sscanf() failed
Note that if the names you are dealing with contain first name and surname, possibly with middle initial, and with 5 numbers (all on a single line), then you probably need a different process. You'd likely use getline() to read a whole line, and then attempt to parse it with sscanf() (or perhaps you'd use a stringstream instead). You'd have to deal with fewer than 5 numbers on the line, of course. I/O is always tricky, especially when you have to deal with erroneous data too (and production-quality code always has to be ready to deal with erroneous data).
Basically you specify a string format in second argument to sscanf function substituting variables you want to
parse with placeholders.
Say, you know that your file consists of following lines:
Father bought 8 bottles of rum on day 1.
Father bought 11 bottles of rum on day 2.
Father bought 5 bottles of rum on day 3.
Father bought 19 bottles of rum on day 4.
You don't care about anything in that string other than amount of bottles for each day.
You fix the parts that do not change, i.e. "Father bought bottles of rum on day"
and specify a placeholder for parts that you want to extract from the string.
Your code would look like that:
int nDay, nBottles;
sscanf(str.c_str(), "Father bought %d bottles of rum on day %d", &nBottles, &nDay);
cout << "Day: " << nDay << ", bottles: " << nBottles << endl;
The symbol after % just specifies the type of variable that part would be parsed to. d here means decimal.
Simply use sscanf(str.c_str(), "%d", &myint) instead of sscanf(str, "%d", &myint).
I see the others explained about sscanf, but I think your question is a little bit different.
sscanf is a C function, but you can use it in C++ because C++ includes C. sscanf basicly takes a string, divide it as you will show and then assign these parts to variables. But there is no such a thing called string in C. Because of this, sscanf takes its parameter as char* namely char pointer which basicly do the same job with string.
In C++, you should use c_str() function to convert string to char pointer.