"printf" on strings prints gibberish - c++

I'm trying to print a string the following way:
int main(){
string s("bla");
printf("%s \n", s);
.......
}
but all I get is this random gibberish.
Can you please explain why?

Because %s indicates a char*, not a std::string. Use s.c_str() or better still use, iostreams:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("bla");
std::cout << s << "\n";
}

You need to use c_str to get c-string equivalent to the string content as printf does not know how to print a string object.
string s("bla");
printf("%s \n", s.c_str());
Instead you can just do:
string s("bla");
std::cout<<s;

I've managed to print the string using "cout" when I switched from :
#include <string.h>
to
#include <string>
I wish I would understand why it matters...

Why don't you just use
char s[]="bla";

Related

How to read a line using scanf in c++?

I'm trying to use "scanf" to read a string line: "is it not working", but I don't know if it's even possible to implement it in this particular example.
#include <iostream>
#include <iomanip>
#include <limits>
#include <string>
using namespace std;
int main() {
int i = 4;
double d = 4.0;
string s = "Just an example of, why ";
int number;
double doub;
string longText;
scanf("%d %lf %s", &number, &doub, &longText); //Read a line ex ("is it not working")
printf("%d\n%lf\n%s", number+i, doub+d,s+longText); //Print all the values, but not printing s+longText
}
Image showing the code
%s in printf/scanf family stands for char array, not std::string. If you want to get line, use std::getline. If you want to use std::string buffer for stdio functions, use std::string::data function, but I wouldn't suggest that as buffer-overflow is likely, especially for something like get-line.

Character Array of dynamic length

I have written a C++ Function which can be represented as below:
All it does is take a string (this is where it crashes) and reverse it.
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int main()
{
cout<<"Enter a string: "<<endl;
char *str;
gets(str);
cout<<"Reversed String is: ";
for(int i=strlen(str)-1;i>=0;i--)
cout<<(str[i]);
return 0;
}
I guess there's some kind of memory access violation.
Any clue why this doesn't work?
Error: Segmentation fault (core dumped)
In c++ there is way more easier and less error prone solution to this problem via std::reverse from algorithm. Also its easier to use std::string.
#include <iostream>
#include <algorithm>
int main ()
{
std::string input;
std::cout << "Enter string to reverse: ";
std::cin >> input;
std::reverse(input.begin(),input.end());
std::cout << "Reversed string: " << input << std::endl;
return 0;
}
If you have to do it via char arrays, try this (you dont even need dynamic memory allocation)
#include <iostream>
#include <algorithm>
#include <cstring>
int main ()
{
char input[1024];
puts("Enter string to reverse: ");
fgets(input, 1024, stdin);
std::reverse(input, input + strlen(input));
printf("Reversed string: %s", input);
return 0;
}
Your code isn't c++ style and I recommend you take a look at the answer from Filip (https://stackoverflow.com/a/45903067/4386427)
I'll just address what goes wrong with your code.
When you do
char* str;
all you get is a pointer that can point to a char. You don't get any memory for holding a char. Further the value of the pointer variable str is uninitialized.
So when you do
strlen(str)
you read an uninitialized variable and try to treat this uninitialized value as a C-style string. That is undefined behavior and is very likely to cause a program crash.
You need to make sure that str is initialized before using it. As you want dynamic memory, you could do:
char *str;
str = new(char[100]); // Initialize str to point to a dynamic allocated
// char array with size 100
...
...
delete(str);
But again - I wouldn't use this style in c++ code

SScanf for CString not working?

I just want to split this string by the char ":"
for example "first:last"
so one string will have "first" and the other will have "last"
I did like the one in this url (sscanf string splitting not working)
but it didn't work well with me as both strings will have the "last" value
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <cstring>
#include<tchar.h>
#include<atlstr.h>
using namespace std;
void main()
{
CString firstString(""), secondString(""), myString("first:last");
sscanf(myString, "%[^:]:%s", firstString, secondString);
printf("first: %s, last: %s", firstString, secondString);
system("pause");
}
As mentioned above, do not mix C "strings" and MFC CStrings. Here's a solution using MFC CString:
const int iColon = myString.Find(':');
if (iColon >= 0)
{
firstString = myString.Left(iColon);
secondString = myString.Mid(iColon+1);
}

File not showing last Character of string when written in file

This snippet is part of a big program. The problem I am facing is that when I write a string to the file using "write" member function, it do not show last character of string:
#include <iostream>
#include <cstring>
#include <string>
#include <cctype>
#include <fstream>
#include <cstring>
using namespace std;
int main()
{
fstream file1("/users/xxxxxxx/desktop/file1.txt", ios::out);
string data;
cout << "Enter string: " << endl;
getline(cin, data);
file1.write(reinterpret_cast<char*>(&data), data.size());
//file1 << data;
file1.close();
return 0;
}
For Example: If Input String: "Hello World".
On File it will show: "Hello Worl",
But it does work fine if I input string using "file1 << data". Please help me in this
file1.write(reinterpret_cast<char*>(&data), data.size());
Don't do this, you are writing the string object itself to the file. if you really want to use write you have to get a pointer to the first char that the string holds, like this:
file1.write(data.data(), data.size());
Just use the << operator.
Why would you cast the address of a string into a char*? This isn't a meaningful conversion--you are casting a std::basic_string<char>* to char*. I suspect you want to treat string as char* since write accepts const char* as parameter. You can access the character sequence stored in your data by doing data.c_str().

Is there a quick way to check if a string is numeric?

Is it possible to check if a string variable is entirely numeric? I know you can iterate through the alphabets to check for a non-numeric character, but is there any other way?
The quickest way i can think of is to try to cast it with "strtol" or similar functions and see whether it can convert the entire string:
char* numberString = "100";
char* endptr;
long number = strtol(numberString, &endptr, 10);
if (*endptr) {
// Cast failed
} else {
// Cast succeeded
}
This topic is also discussed in this thread: How to determine if a string is a number with C++?
Hope this helps :)
#include <iostream>
#include <string>
#include <locale>
#include <algorithm>
bool is_numeric(std::string str, std::locale loc = std::locale())
{
return std::all_of(str.begin(), str.end(), std::isdigit);
}
int main()
{
std::string str;
std::cin >> str;
std::cout << std::boolalpha << is_numeric(str); // true
}
You can use the isdigit function in the ctype library:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main ()
{
char mystr[]="56203";
int the_number;
if (isdigit(mystr[0]))
{
the_number = atoi (mystr);
printf ("The following is an integer\n",the_number);
}
return 0;
}
This example checks the first character only. If you want to check the whole string then you can use a loop, or if its a fixed length and small just combine isdigit() with &&.