char str1[10];
fscanf(fp , "%s", str1);
I want to know size of %s before assigning to str1 to avoid crashing in case of huge input data.
Since this is C++, you don't have to rely on fscanf. We can avoid buffer overflow altogether by using std::istream:
std::string readWord(std::istream& input) {
std::string word;
if(input >> word) {
return word;
} else {
// Handle error
}
}
This will automatically read characters until reaching the first whitespace character is encountered, and it'll automatically allocate memory as needed.
You can specify the maximum number of characters to read:
fscanf(fp, "%9s", str1);
This will not write more than 10 chars into str1 including the null terminator.
But in C++ you should use streams and strings which are safe in this respect.
Related
As the title says, how do I replace a string with another string? For example: the user would enter three inputs. The first input is the string that the program would replace; the second is the string that would replace input1; and the third is the string that would be printed out. So if:
Input1 = peanut
Input2 = coconut
Input3 = replacepeanutreplace
Output: replacecoconutreplace
I have started it but my program can only replace words with the same length. I tried searching my problem, but I do not understand the given solutions since I am just new at C/C++.
char replacing[100];
char replacement[100];
char original[1000];
int count;
cin >> replacing;
cin >> replacement;
while(! cin.eof())
{
cin >> original;
char * pch;
pch = strstr (original, replacing);
count = strlen(replacement);
strncpy (pch, replacement, count);
cout << original << endl;
}
What about:
You first find (if any) an occurrence of that string
Use replace to substitute the occurrence with the second string
Here is something that should work:
bool replaceFirst(string& input, const std::string& toBeReplaced, const std::string& replacement) {
size_t start_pos = input.find(toBeReplaced);
if(start_pos == std::string::npos)
return false; //substring not found!
input.replace(start_pos, toBeReplaced.length(), replacement); //found. now i can replace!
return true;
}
Since you are using an array of char instead of string you have to make sure that replacing does not lead you out of bound (strings auto-resize for you).
The key problem is that strncpy does not allocate (or free) any memory. This means that if replacement is shorter that replacing, part of replacing will not be overwritten. Similarly if replacement is longer it will overwrite beyond the end of replacing.
As already said, you would be better off using std::string (or some other C++ string class like Qt's QString if Qt is your cup of tea).
One other little thing, in general with streams it's best not to just check for eof, rather write something like
while (cin >> original) {
This will terminate if the stream is in any fail state, not just eof.
int size;
cout<<"enter string size"<<endl;
cin>>size;
char * string1 = new char[size];
well hello,im working on a project and one of my functions purpose is to get a dynamic char array as arg which sends to the output the first letters of the words in the string.
so the user decides the string length (for the initialized dynamic array),
but then how can i ensure he won't exceed the length of the array he chose?(the compiler does not Refer to it as a mistake).
can i force the 'cin' operator to limit itself?
Using std::string is better, but...
char input [8];
cin.getline (input, 8);
Note, there may still be data in the input buffer after this that you may need to deal with.
Edit
Given the original code in the question:
cin.getline(string1, size);
Just have them input into a std::string. Don't bother with the manual memory management.
std::cout << "Enter your name.\n> ";
std::string name;
std::cin >> name;
Then, if you need to only pass the first 8 characters or something, use name.substr(...).
You really ought to be std::string, but if you really want to use a character array, you should use:
cin.getline(string1, 8);
This gets 8 characters from the user input.
cin getline works as followed:
It extracts characters, without any formatting and storms them as an c-string. It will stop extracting characters when either the new line character is reached, a set char deliminator, or until the number of characters specified has been extracted.
You can make this approach with std::string. For example:
const int maxchar = 8;
string str;
cin >> str;
if (str.size() > maxchar )
{
err << "The input is too long." << endl;
return 1;
}
I need to read a text file that's in this format:
n k
S1
S2
S3
.
.
.
Sn
N being and integer, and S's being strings. Now, as far as I've seen a string cannot be read with fscanf function, but rather an array of char's has to be used.
The problem is that I need to set the length of the character array even though I have no way of knowing how long a word will be:
in = fopen("01.in", "r");
int N, k;
fscanf(in, "%d %d", &N, &k);
for (int i=0; i<N; i++){
char temp[100];
fscanf(in, "%s", temp);
}
So is there a way to maybe use vectors or something?
Or maybe in the off case that this problem cannot be solved, can I convert a string of chars into a string, and then create a vector of strings?
Why not use std::ifstream and std::getline something like this:
std::ifstream in("01.in");
int N, k;
if(!(in >> N >> k))
{
std::cerr << "Error reading file!" << '\n';
return EXIT_FAILURE;
}
std::string line; // read lines into this
int i = 0;
while(i < N && std::getline(in, line))
{
// deal with line here
++i; // keep track
}
The first step towards code sanity here is to stop using char arrays and start using std::string instead. The big difference between the two is that an array's size is set in stone at compile time, whereas a std::string's initial size can be can be chosen at runtime, and it can also grow and shrink while the program runs.
Now, as far as I've seen a string cannot be read with fscanf function,
but rather an array of char's has to be used.
Since C++11, that's not strictly true. std::strings are in many ways compatible with C functions. For example, you can safely get a pointer to the underlying buffer with &s[0]. Therefore, you could technically do this:
std::string temp(100, '\0');
fscanf(in, "%s", &temp[0]);
But that has not gotten us far. Apart from some other bad things about this "solution" (unidiomatic, undefined behaviour if too many characters are read, wasteful if too few characters are read), as you can see, the original problem still persists; the number 100 is hard-coded in the program. This is the real problem, as you have also said in the comment you added:
What I mean is what if I get a string that's longer than 100 characters?
The answer to that is: Just don't use fscanf anymore. Use std::ifstream along with the std::getline function. std::getline reads a whole line, i.e. everything until the next line break, and stores the result in a std::string. Size and memory management are all handled automatically for you:
std::ifstream is("01.in");
std::string temp;
std::getline(is, temp);
I want to read from a file character by character and perform a certain operation on every character I am using the following loop:
ifstream in
while(in)
{
ch=in.get();
//some operation
}
I don't want to read the character in condition for while because then cursor will move to next position and I'll miss that character.
The problem is that the end of the file is not properly signalled and the last character is read two times. Please give a way to avoid this
Eg. if The string in the file is
army
it is read as armyy (when I print)
char ch;
while(in.get(ch)){ } //or in>>std::noskipws>>c
Would be the proper way as the character you want is stored in ch. what is the problem with that?
If you really want it the way you want, then you may use peek() to see the next character and perform appropriate opeartion as:
char c = in.peek(); //this will give you the next character in the stream
//if its an eof, do appropriate
Use the other overload of get:
while (in.get(ch)) {
// do something with ch
}
or
for (char ch; in.get(ch); ) {
// do something with ch
}
You can also use sscanf for reading char.. In that example you can see that 3 input are reading from text . First two are string , last is float .. And also you can use a vector to store values..
Hope this example can be helpfull
std::string str;
char buf_1[50];
char buf_2[50];
while(std::getline(in, str))
{
if(sscanf(str.c_str(), "%s %s %f", buf_1, buf_2, &faceStatistics.statistics) == 3)
{
faceStatistics.faceName_1 = buf_1;
faceStatistics.faceName_2 = buf_2;
faceStat_.push_back(faceStatistics);
}
else
std::cout << "No param in string " << str << std::endl;
}
vector assign
struct Fstat {
std::string faceName_1;
std::string faceName_2;
float statistics;
};
How would you get the size input string to console or size of valid characters in buffer?
char buffer[100];
cin >> buffer;
I'm looking to put the '\0' where the input ends.
Prefer using std::string, instead of char* or char[]. That makes such things easy! The problem with char buffer[100] is that if the size of input string is more than 100, then your cin >> buffer would invoke undefined behavior, as it would attempt to write beyond the array. This problem can easily be avoided if you use std::string.
std::string input;
cin >> input; //this can read string of any unknown size!
cout << "length of input string : " << input.size()<< endl;
You can also use input.length() instead of input.size(). They return the same value.
Online Demo : http://www.ideone.com/Wdo31
The question is moot. When the user types more than 100 characters, you have a buffer overrun. You may crash. If not, you got a security issue at best. You shouldn't do this. Read the input a character at a time, or use a safer string library. gets_s comes to mind if it's supported on your platform.
But in answer to your question, this might be what you need:
char buffer[100] = {}; // zero-init the entire array
int length = 0;
cin >> buffer;
length = strlen(buffer); // length is the length of the string
You don't need to (and quite possibly, can't). Instead, use a std::string instead of a char buffer.