C++ strtok function - c++

char ParseCmd(char *buf,int len)
{
char *p;
p = strtok(buf," ");
return *p;
}
Why does this function only return first symbol in a whole buffer? If I set buffer to a "fsa rew qwe" it returns only "f" instead of the expected "fsa".
"mˣ*" - that is now im getting. why ?
char dum = *InstList->Lines->GetText();
LoadLibrary("SyntaxP.dll");
char *dum1 = ParseCmd(&dum,32);
InstList->Lines->Add(dum1);

Because your return type is char which represents a character and you dereference the pointer returned by strtok().

Because you are returning a char value, which means only the first character of the string pointed by pointer p.You should return a char * from your function.
Your function should have the prototype:
char* ParseCmd(char *buf,int len);
^^^^^
Online Demo:
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
char* ParseCmd(char *buf,int len)
{
char *p;
p = strtok(buf," ");
char *ptr = (char *)malloc(strlen(p)+1);
strncpy(ptr,p,strlen(p));
return ptr;
}
int main()
{
char array[]="fsa rew qwe";
char* ret = ParseCmd(array,11);
printf("[%s]",ret);
/*If You Forget this,You cause a Memory Leak*/
free(ret);
return 0;
}
Output:
[fsa]
Disclaimer: I have not really used any C++ in the code because since You are using strtok and char * instead of string I believe the Q is more C than C++.

Like any C-style string, p is actually a character array. If you dereference it, you get a character. Have your ParseCmd return p instead of return *p.

Related

Copying char* with char symbol

I am trying to copy a char* and char symbol into a new char* , however the desired result after copying is wrong.
char* name = "someData";
char symbol ='!';
int size1 = strlen(name);
int size2 = 1;
int newSize = size1 + size2 + 1;
char* res = new char[newSize];
strcpy(res,name);
const char* symbolPointer = &symbol;
strcat(res, symbolPointer);
cout<<*res;
I expect the result to be "someData!" , however it is only "s" , where is my mistake?
char* name = "someData";
This is an ill-formed conversion in C++ (since C++11). I recommend to not point to string literals with pointer to non-const.
const char* symbolPointer = &symbol;
strcat(res, symbolPointer);
Both arguments of std::strcat must be null terminated. symbolPointer is not a pointer to a null terminated string. Because the pre-condition of std::strcat is violated, the behaviour of the program is undefined.
cout<<*res;
res is a pointer to the first character of the string. By indirecting through the pointer to first character, you get the first character. That is why you see the first character (in case the undefined behaviour hasn't caused the program to do something completely different).
Lastly, the program leaks the allocated res.
Here is a fixed example:
std::string name = "someData";
name += '!';
std::cout << name;
The problem is the following:
cout<<*res;
This is equivalent to:
cout << res[0];
It prints just the first character of the output. Use
cout<<res;
Try it this way:
const string name = "someData";
const char symbol ='!';
string res = name + symbol;
cout << res;
You should avoid the legacy C nul-terminated string handling functions. You should avoid using new directly in your code.
The observed result you are asking about is due to you writing *res (a single character) instead of res (a pointer to the first character) in the output statement. But the code was buggy besides that, as strcat will copy until it finds the terminator, so it will overwrite some unknown amount of memory beyond what you allocated.
symbolPointer should end with null character, because strcat requires 0-terminated string.
So if you want to continue on your way,
(not a good idea but)
You can add this before strcat.
*(symbolPointer+1) = 0;
#include <iostream>
#include <cstring>
int main() {
char name[] = "someData";
char symbol ='!';
int size1 = strlen(name);
int size2 = 1;
int newSize = size1 + size2 + 1;
char* res = new char[newSize];
strcpy(res,name);
char* symbolPointer = &symbol;
*(symbolPointer + 1) = 0;
strcat(res, symbolPointer);
cout<<res;
return 0;
}

Pass char array on to a function C++

My goal is to take in a character array and replace specific words such as "class" with the word "video". However, the data in buf array is coming from a web server that has unicode in it, so to my knowledge, I am not allowed to convert the char array into a string because it will mess up much of the data in it (I think).
So, my main question is, how do I pass buf in as an argument to the replaceWords function. Right now I get an error that says,
error: incompatible types in assignment of ‘char*’ to ‘char [256]’
char buf[256];
buf = replaceWords(buf);
char * replaceWords(char* buf) {
char badWord1[] = "class";
char * occurrence = strstr(buf, badWord1);
strncpy(occurrence, "video", 5);
return buf;
}
The error is caused by buf = replaceWords(buf);. This tries to assign the function return value (char*) to an array and that's not valid syntax.
Your code passes the array to the function and the function changes the character string in-place. You don't need the return value from the function. In fact, the function could just be defined as returning void and then you can remove the return statement.
Note: you should probably add some error checking. What happens if the badWord1 string is not found and strstr() returns NULL?
Look at this code:
#include <bits/stdc++.h>
using namespace std;
void replaceWords(char buf[]) {
char badWord1[] = "class";
char * occurrence = strstr(buf, badWord1);
strncpy(occurrence, "video", 5);
}
int main() {
char temp[5];
temp[0] = 'c';
temp[1] = 'l';
temp[2] = 'a';
temp[3] = 's';
temp[4] = 's';
replaceWords(temp);
cout << temp << endl;
return 0;
}
It will work as you intend. When you pass char buf[] you are passing a reference to the array you want to modify. That way you can modify it in the function and it will be modified everywhere else in the program. There's not need to do additional assignment.

Combine sizeof string and chararcter

The last 2 cout statements have the same size. why?
int main()
{
char ch=127;
cout<<sizeof(ch)<<endl; //Size=1
cout<<sizeof("Hello")<<endl; //Size=6
cout<<sizeof("Hello"+ch)<<endl; //Size=8
cout<<sizeof("HelloWorld"+ch)<<endl; //Size=8
return 0;
}
Please explain.
Thanks
When you do "Hello"+ch the array containing the string "Hello" decays to a pointer to its first element, and you add ch to this pointer.
The result of pointer arithmetic is a pointer, which is what you get the size of.
Equivalent code would be something like
char const hello[] = "Hello";
char const* phello = hello; // equivalent to &hello[0]
char const* result = phello + ch;
cout << sizeof(result) << endl;

Why do I return a series of a chars for a pointer return type?

I am trying my best to return a pointer with a specific value. Though, I am not understanding why I am getting more chars than usual. I asked a few people and I was told that I am getting a substring?
Problem: I type in the word hotdog.
I expect to return a pointer at the index[2]. Though instead, I get the chars dog. Why is that? How would I get just index[2]? I am thinking about dereferencing it, but I am having problems in getting the return type to work.
I cannot change the return type or parameters for my function.
#include <iostream>
char * GetValueAtIndex(char * const c, int index);
void ReadString(char * c, int length);
int main()
{
const int size = 10;
char ma[size];
char * pointer = ma;
ReadString(ma, 20);
std::cout << GetValueAtIndex(pointer, 3) << std::endl;
system("pause");
}
void ReadString(char * c, int length)
{
std::cin.getline(c, length);
}
char * GetValueAtIndex(char * const c, int index)
{
return c + index;
}
Modify your function to return a value not a pointer:
char GetValueAtIndex(char * const c, int index){
return *(c + index);
}
or simply dereference a pointer returned by a function:
std::cout << *GetValueAtIndex(pointer, 3);
When you have a char* pointer like:
char* p = "Hotdog";
and send that p to std::cout it will be treated as a pointer to (a first character of a) C style string and printed as such. C style strings end with \0. So it will print out whatever the character the p points to followed by all the remaining characters until it reaches the end of the string that is \0.
If you increment a pointer it then points at the next character etc:
char* p = "Hotdog";
p++;
std::cout << p;
p+=3;
std::cout << p;
If you just need to print a single character the p points at then send a dereferenced pointer to std::cout:
char* p = "Hotdog";
std::cout << *p;
Why do I return a series of a chars for a pointer return type?
You return a pointer to a character, exactly as you state what you're trying to do.
I expect to return a pointer at the index[2]
That pointer was returned, as you expected.
Though instead, I get the chars dog.
That is because you insert the pointer into a stream. The stream insertion operator for char* requires that the input is a pointer to a null terminated string and the behaviour is to print that entire string. Your pointer points to an array of chars starting from the character 'd'.
I am thinking about dereferencing it
If you dereference the pointer, you will get the character that is pointed to ('d'):
std::cout << *GetValueAtIndex(pointer, 3) << std::endl;

How to copy a string into a char array with strcpy

I my trying to copy a value into a char.
my char array is
char sms_phone_number[15];
By the way, could tell me if I should write (what the benefic/difference?)
char * sms_phone_number[15]
Below displays a string: "+417611142356"
splitedString[1]
And I want to give that value to sms_from_number
// strcpy(sms_from_number,splitedString[1]); // OP's statement
strcpy(sms_phone_number,splitedString[1]); // edit
I've got an error, I think because splitedString[1] is a String, isn't?
sim908_cooking:835: error: invalid conversion from 'char' to 'char*'
So how can I copy it correctely.
I also tried with sprintf without success.
many thank for your help.
Cheers
I declare spliedString like this
// SlitString
#define NBVALS 9
char *splitedString[NBVALS];
I have that function
splitString("toto,+345,titi",slitedString)
void splitString(char *ligne, char **splitedString)
{
char *p = ligne;
int i = 0;
splitedString[i++] = p;
while (*p) {
if (*p==',') {
*p++ = '\0';
if (i<NBVALS){
splitedString[i++] = p;
}
}
else
{
p++;
}
}
while(i<NBVALS){
splitedString[i++] = p;
}
}
If I do a for with splitedString display, it display this
for(int i=0;i<4;i++){
Serialprint(i);Serial.print(":");Serial.println(splitedString[i]);
}
//0:toto
//1:+4176112233
//2:14/09/19
I also declared and want to copy..
char sms_who[15];
char sms_phone_number[15];
char sms_data[15];
//and I want to copy
strcpy(sms_who,splitedString[0]
strcpy(sms_phone_number,splitedString[1]
strcpy(sms_date,splitedString[2]
I know, I am very confused with char and pointer * :o(
The declaration:
char * SplittedString[15];
Declares an array of pointers to characters, a.k.a. C-style strings.
Given:
const char phone1[] = "(555) 853-1212";
const char phone2[] = "(818) 161-0000";
const char phone3[] = "+01242648883";
You can assign them to your SplittedString array:
SplittedString[0] = phone1;
SplittedString[1] = phone2;
SplittedString[2] = phone3;
To help you a little more, the above assignments should be:
SplittedString[0] = &phone1[0];
SplittedString[1] = &phone2[0];
SplittedString[2] = &phone3[0];
By definition, the SplittedStrings array contains pointers to single characters, so the last set of assignments is the correct version.
If you are allowed, prefer std::string to char *, and std::vector to arrays.
What you need is a vector of strings:
std::vector<std::string> SplittedStrings(15);
Edit 1:
REMINDER: Allocate space for your spliedString.
Your spliedString should either be a pre-allocated array:
char spliedString[256];
or a dynamically allocated string:
char *spliedString = new char [256];
Strings and Chars can be confusing for noobs, especially if you've used other languages that can be more flexible.
char msg[40]; // creates an array 40 long that can contains characters
msg = 'a'; // this gives an error as 'a' is not 40 characters long
(void) strcpy(msg, "a"); // but is fine : "a"
(void) strcat(msg, "b"); // and this : "ab"
(void) sprintf(msg,"%s%c",msg, 'c'); // and this : "abc"
HTH