Hi what is the solution ?

i have a file like this :
0 1 2 C
10 1 2 S
7 1 2 C
11 1 2 S
9 3 43 C
10 3 43 S
1 3 43 C
101 3 43 S

with this code :

ifstream in("fout2.txt");
    if (in) {
    vector<string> lines;
    string line;
while (getline(in, line))
lines.push_back(line);
sort(lines.begin(), lines.end(), [](const string& a, const string& b) {
// Use the first word for comparison
return a.substr(0, a.find_first_of(' ')) <
b.substr(0, b.find_first_of(' '));
    });
for_each(lines.begin(), lines.end(), [](const string& s) {
std::cout << s << '\n';
    });
}

i obtaint this :

0 1 2 C
1 3 43 C
10 1 2 S
10 3 43 S
11 1 2 S
101 3 43 S
7 1 2 C
9 3 43 C

but i want an output like this :

0 1 2 C
1 3 43 C
7 1 2 C
9 3 43 C
10 1 2 S
10 3 43 S
11 1 2 S
101 3 43 S

thanks

Dani AI

Generated

Your comparator is comparing the first token as text, so 101 sorts before 7 (lexicographic order). The fix is to parse the first token as a number and sort by that numeric key. As suggested, convert the first token to an integer — but avoid a plain map<int,string> because identical keys will overwrite earlier lines; use a multimap, map<int,vector<string>>, or better: pair each line with its parsed key and sort. Also note 's selection approach works but is O(n^2); prefer std::stable_sort (O(n log n)) if you want to preserve the original order for equal keys.

A compact, robust workflow:

  • read all lines into vector<string>,
  • parse the leading integer for each line,
  • build vector<pair<long long,string>>,
  • stable_sort by the numeric key,
  • output the stored strings.

Example (C++11-compatible parse + stable sort):

long long parseLeadingNumber(const std::string &s) {
    const char *p = s.c_str();
    while (*p && std::isspace((unsigned char)*p)) ++p;
    bool neg = false;
    if (*p == '+' || *p == '-') { neg = (*p == '-'); ++p; }
    long long v = 0;
    while (*p >= '0' && *p <= '9') { v = v*10 + (*p - '0'); ++p; }
    return neg ? -v : v;
}

std::vector<std::pair<long long,std::string>> keyed;
for (auto &ln : lines) keyed.emplace_back(parseLeadingNumber(ln), ln);
std::stable_sort(keyed.begin(), keyed.end(),
                 [](const auto &a, const auto &b){ return a.first < b.first; });
for (auto &p : keyed) std::cout << p.second << '\n';

Notes and pitfalls: use long long (or unsigned) if numbers may be large; std::from_chars is faster and non-throwing if your standard library supports it; handle lines without leading digits explicitly (place them last or treat as zero); for files too large to hold in memory, use an external sort or a streaming/multi-pass algorithm. This approach produces the numeric order shown in your desired output while preserving the input order for equal keys.

Recommended Answers

All 2 Replies

You could try an algorithm as follows:

Create a new list that has your sorted list.
input_list -> initially has unsorted lines.

while ( !input_list.empty() ) {
  search smallest element, add this to a new list. // this is a O(n) operation.
  delete this entry from input_list. 
}

HTH.

The simplest solution is to convert the first token (that is, the first contiguous series of characters) of each line to an integer, and sort by the integers. Given this approach, it would then make more sense to use an STL map(), which automatically sorts itself according to a predicate passed as an optional template parameter, rather than sorting the list after the fact. Since the default sorting uses the less comparison, you may not even need the predicate.

std::map<int, std::string> sorted_strings = std::map<int, std::string>(); 

while (getline(in, line)) 
{
    std::stringstream ss;
    ss << in;
    int key;
    ss >> key;
    sorted_strings[key] = in;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.