is there another way to get rid of warnings

Aside form adding those arguments to compile command, is there another way to do this without getting warnings? Also is the warnings the reason to why whitespace other than a space are being ignored?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <string>
#include <vector>

using namespace std;

void split(const string s, vector<string> &v, char sep=NULL){
    string index = "";
    for (int i=0; i<s.length(); i++){
        if (sep != NULL){
            if (s[i] == sep){
                v.push_back(index);
                index = "";
            }
            else{
                index += s[i];
            }
        }
        else{
            if (isspace(s[i])){
            //if (s[i] == ' ' || s[i] == '\n' || s[i] == '\t'){
                if (index.length()){
                    v.push_back(index);
                   }
                index = "";
            }
            else{
                index += s[i];
            }
        }
    }
    if (index.length()){
        v.push_back(index);
       }
}

void print(vector<string> v){
    for (int i=0; i<v.size(); i++){
        cout << "[" << v[i] << "]";
    }
}

int main(){
    string s;
    vector<string> v;
    while (true){
        std::cout << "\n: ";
        getline(cin, s);
        split(s, v);
        print(v);
        v.clear();
    }
    
    /*
    vector<string> v;
    split("some random string sitting here", v,' ');
    print(v);
    std::cout << '\n';
    vector<string> v2;
    split("some random string\nsit\nting \t\t\n   \n\there\n", v2);
    print(v2);
    */
}



output:
1
2
3
4
5
6
7
8
9
test.cpp: In function ‘void split(std::string, std::vector<std::basic_string<char> >&, char)’:
test.cpp:10:20: warning: NULL used in arithmetic [-Wpointer-arith]
test.cpp: In function ‘int main()’:
test.cpp:49:19: warning: converting to non-pointer type ‘char’ from NULL [-Wconversion-null]

: test\t \t \ttest
[test\t][\t][\ttest]
: 
Last edited on
Aside form adding those arguments to compile command, is there another way to do this without getting warnings?

To get rid of these warnings you just have to fix the (minor) defects in your code.

sep is of type char so you should be testing it against the null char '\0' not NULL, which for old-style pointers (C++11 code should use nullptr instead of NULL.)

I aslo changed the type of i from int to size_t, as that's in step with what string::size returns (an unsigned rather than signed value.)

1
2
3
4
5
6
7
8
9
10
11
12
13
void split(const string s, vector<string> &v, char sep='\0'){
    string index; // string sets itself to "" automatically
    for (size_t i=0; i<s.length(); i++){
        if (sep != '\0'){
            if (s[i] == sep){
                v.push_back(index);
                index.clear(); // rather than = "";
            }
            else{
                index += s[i];
            }
        }
        // etc 


Also is the warnings the reason to why whitespace other than a space are being ignored?

Nope -- looks like it should work ok (for spaces and tabs)

(both NULL and '\0' are zero, so aside from the cast, the maths will be ok.)

Andy
Last edited on
you should be testing it against the null char '\0' not NULL

i didnt know there was one specifically for char, thanks.


off topic but regarding the same code:
After that modification though the output is not what i expect it. It appears that it is not splitting the string up by tabs and newlines, but only by a single space?
the output:
1
2
3
4
5
6
7
: test test
[test][test]
: test\ttest
[test\ttest]
: test\ntest
[test\ntest]
: 


i expected the output to be:
1
2
3
4
5
6
7
: test test
[test][test]
: test\ttest
[test][test]
: test\ntest
[test][test]
: 
Tabs work for me (but you enter them with the tab key, not as \t -- that only works when compiling strings!?)

But getline is using \n for the delimiter, so these will never get through to your code.

Andy
Last edited on
you enter them with the tab key, not as \t -- that only works when compiling strings

oh ok, thanks again. IS there a way to take the string in raw? to be able to do this?

yeah i was more or less using getline() to test in repetition
Last edited on
If you want to be able to enter tab and newline using C++ syntax, you'll need to process your string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string unescape(const string& s){
    string ret;
    const size_t len = s.length();
    for (size_t i=0; i<len; i++){
        if((i < (len - 1)) && ('\\' == s[i])){
            switch(s[i + 1]){
                case 't': ret += '\t'; ++i; break;
                case 'n': ret += '\n'; ++i; break;
                default: ret += s[i];
            }
        } else {
            ret += s[i];
        }
    }
    return ret;
}


called after getline like

s = unescape(s);

: hello\tworld
[hello][world]
: one\ntwo\nthree
[one][two][three]
:


Andy
> is there another way to get rid of warnings

When the compiler issues a warning diagnostic, it is trying to help the programmer by pointing out a possible error in the code. Do not turn them off by default; while writing code, we need all the help that we can get. Compile with warnings enabled at the highest level available.

If after we have looked at a warning, analyzed it, and satisfied ourselves that things are ok despite the warning, we can opt to suppress that specific warning for that specific part of code by appropriate #pragma directives. (Ideally along with a comment explaining why it has been disabled).

For instance, with the GNU toolchain:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <string>
#include <iostream>

int main()
{
    std::string str = "abcdef" ;

    // turn off the warning: comparison between signed and unsigned integer expressions
    // we know that it is safe to ignore it in this particular case
    #pragma GCC diagnostic push // save the current state
    #pragma GCC diagnostic ignored "-Wsign-compare"

    for( int i = 0 ; i < str.size() ; ++i ) std::cout << str[i] ;

    #pragma GCC diagnostic pop // restore the previous state

    // ... ;
}
closed account (N36fSL3A)
for (unsigned int i=0; i<s.length(); i++)
i dont put unsigned for the 9 extra keystrokes
> i dont put unsigned for the 9 extra keystrokes

Use a type alias. For instance using uint = unsigned int ;

or using pos_t = std::string::size_type ;
Topic archived. No new replies allowed.