Spalten aus CSV-Datei umwandeln und absteigend sortieren
-
Hallo Leute,
keiner mehr da?
MfG Flo
-
Du müsstest schon deinen Code posten, damit man dir helfen kann. Ich glaube niemand hat eine so mächtige Glaskugel.
-
Schade wer doch mal was schönes so ne Glaskugel
Nun der Code:
#include <string> #include <iostream> #include <conio.h> #include <fstream> #include <ctime> #include <strstream> #include <sys/timeb.h> #include <sstream> using namespace std; ifstream input("input.csv",ios::in); fstream output("output.csv",ios::out); int number_of_input_lines; string line_content = "0", line_number = "0"; // Column number and the rest of the column content int loop_counter = 0; // variable to input the number of the convert figures, loop counter const int inputs_per_line = 7; // number of inputs per column const int max_line_number = 31750; // number of column inputs string line_output[max_line_number]; // to the descending output of the columns int array_number[inputs_per_line]; int array_anzahl = sizeof(array_number) / sizeof(array_number[array_anzahl]); int int_line_number; void dec2bin(long decimal, char *binary) // decimal-to-binary conversion { int k = 0, n = 0; int neg_flag = 0; int remain; int old_decimal; char temp[80]; if (decimal < 0) { decimal = -decimal; neg_flag = 1; } do { old_decimal = decimal; remain = decimal % 2; decimal = decimal / 2; temp[k++] = remain + '0'; } while (decimal > 0); if (neg_flag) { temp[k++] = '-'; } else { temp[k++] = ' '; } while (k >= 0) binary[n++] = temp[--k]; binary[n-1] = 0; } string number2roman(int x) // Decimal to Roman numerals conversion { if(x < 1 || x > 1000000000000) throw(x); static const char *rom_strings[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" }; static const int rom_values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }; string rest; for(int i = 0; x != 0; ++i) while(x >= rom_values[i]) { x -= rom_values[i]; rest += rom_strings[i]; } return rest; } int output_program_info() { cout << "Please save the \"input.csv\" file in the same folder \nin which also the CSV-File Reader is existing. \n" << "The column numbers in column 1 to 9 must be written \nlike this in the CSV-File: 01 ... 09. \n" << "The 0 is needed for the converter. \nHow many column must be converted? "; cin >> number_of_input_lines; // input of the column number cout << "\nPress any key to start the conversion ...\n"; getch(); cout << "Conversion is in process...\n"; output << ";;*** CSV File Reader ***\n\n Info:\n"; if (input.is_open() && output.is_open()) { output << " - Input file has been founded and now it is available! \n" << " - First conversion: decimal. \n - Second conversion: octal. \n" << " - Third conversion: hexadecimal. \n - Fourth conversion: binary. \n" << " - Fifth conversion: symbolic. \n" << " - A reference for the fifth column: Only write number not higher than 60.000. Later it's easier to read. \n" << " - All columns get mirrored from to beginning to the end or rather from the end to the beginning. \n\n" << "Column Number: ;Numbers: \n"; } else { output << "Error. No input file."; exit; } return number_of_input_lines; } void timekeeping() { struct _timeb timebuffer1; char *timeline1; _ftime( &timebuffer1 ); timeline1 = ctime( & ( timebuffer1.time ) ); printf( "\t\t\t\t\t\ %.19s.%hu %s", timeline1, timebuffer1.millitm, &timeline1[20] ); } string conversion() { do { if (loop_counter != number_of_input_lines) { getline(input, line_number, ';'); getline(input, line_content); if (line_number <= "05" ) { bool d = line_content.find_first_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIKLMNOPQRSTUVWXYZ") == string::npos; // error control of data if (d != 1) { output << "You made a wrong input in column number " << line_number << ". Fill in only numbers,please." << endl; break; } else { const char *line_content_in_char = line_content.c_str(); sscanf(line_content_in_char, "%i;%i;%i;%i;%i;%i;%i", &array_number[0], &array_number[1], &array_number[2], &array_number[3], &array_number[4], &array_number[5], &array_number[6]); int_line_number = atoi( line_number.c_str() ); { switch(int_line_number) { case 1: { // Conversion line 1 line_output[0] = line_number + ";" + line_content; } case 2: { // Conversion line 2 string line_number02, line_content_02; char content[20]; line_number02 = line_number + ";"; if (array_number[0] == 0) { line_content_02 = "Nothing for outputting!"; } else { for (int i=0; i<array_anzahl; i++) { sprintf(content,"%1o",array_number[i]); line_content_02 = line_content_02 + content + ";"; } } line_output[1] = line_number02 + line_content_02; } case 3: { // Conversion line 3 string line_number03, line_content03; char content[20]; line_number03 = line_number + ";"; if (array_number[0] == 0) { line_content03 = "Nothing for outputting!"; } else { for (int i=0; i<array_anzahl; i++) { sprintf(content,"%1x",array_number[i]); line_content03 = line_content03 + content + ";"; } } line_output[2] = line_number03 + line_content03; } case 4: { // Conversion line 4 char binary[80]; string line_number04, line_content_04, content; line_number04 = line_number + ";"; if (array_number[0] == 0) { line_content_04 = "Nothing for outputting!"; } else { for (int i=0; i<array_anzahl; i++) { dec2bin(array_number[i],binary); content = binary; line_content_04 = line_content_04 + content + ";"; } } line_output[3] = line_number04 + line_content_04; } case 5: { // Conversion line 5 long symbol = 0; string line_number05, line_content_05, content; line_number05 = line_number + ";"; if (array_number[0] == 0) { line_content_05 = "Nothing for outputting!"; } else { for (int i=0; i<array_anzahl; i++) { content = number2roman(array_number[i]) + ";"; line_content_05 = line_content_05 + content; } } line_output[4] = line_number05 + line_content_05; } } } } ++loop_counter; // loop counter for column one two five } else { line_output[loop_counter] = line_number + ";" + line_content; ++loop_counter; // loop counter for the rest of the columns do { getline(input, line_number, ';'); getline(input, line_content); line_output[loop_counter] = line_number + ";" + line_content; ++loop_counter; // loop counter for the rest of the columns } while (loop_counter != number_of_input_lines); } } else { break; } } while (!input.eof()); return line_output[0], line_output[1], line_output[2], line_output[3], line_output[4], line_output[loop_counter]; } int main() // Main program { output_program_info(); timekeeping(); conversion(); timekeeping(); for (int i = number_of_input_lines-1; i>=0; i--) // Mirroring and output { output << line_output[i] << endl; } timekeeping(); output.close(); cout << "Conversion successful.\n\nOpening output file ...\nClose the output file to exit\n"; system("output.csv"); timekeeping(); getch(); }
Gruß Flo
-
Hey,
is noch jemand da?
MfG Flo
-
FlorianB schrieb:
Hey,
is noch jemand da?Hallo Flo,
ja es sind noch viele da, aber bis jetzt hat Dir niemand geantwortet.
Du hast immer noch eine ganze Menge Code (286 Zeilen), die mühsam zu lesen sind, und Deine Frage oben wurde von pumuckl bereits beantwortet.pumuckl schrieb:
FlorianB schrieb:
zu sscanf: das liegt mir auch noch auf dem Herzen. Wie kann ich das in eine Schleife verpacken? bzw. in streams?
sscanf(column_content_in_char, "%i;%i;%i;%i;%i;%i;%i;%i;%i;%i;%i", &array_number[0], &array_number[1], &array_number[2], &array_number[3], &array_number[4], &array_number[5], &array_number[6], &array_number[7], &array_number[8], &array_number[9], &array_number[10]);
Schau dir mal stringstreams an. Vorgehen in dem Fall:
- leerer ostrignstream
- in einer Schleife die Nummern, jeweils gefolgt von einem ';' in den Stream
- string aus dem stringstream holen.
dazu hast Du noch keine Stellung genommen ..
Zerlege Dein Problem doch mal in kleine Häppchen und löse sie eines nach dem anderen.
Anbei mal ein kleines Programm zum Üben des Lesens aus einer csv-Datei:
#include <fstream> #include <iostream> std::istream& semikolon( std::istream& in ) { char semikolon; if( in >> semikolon && semikolon != ';' ) in.setstate( std::ios_base::failbit ); return in; } int main() { using namespace std; const int anzahlSpalten = 20; ifstream input("input.csv"); // kein 'ios::in' das macht der ifstream schon for( int zeile = 0; input; ++zeile ) { int number; for( int spalte = 0; input >> number; ) { cout << "array_number[" << spalte << "] = " << number << "; "; if( ++spalte < anzahlSpalten ) input >> semikolon; else break; } cout << endl; } return 0; }
Du bekommst eher eine Antwort, wenn Du kleine Menge Code postest (ca. ein Dutzend Zeilen) und konkrete Fragen dazu stellst.
Gruß
Werner
-
Hey Leute,
inzwischen hab ich es alleine geschaft.
Das einizge was jetzt noch fehlt, ist das hier:sscanf(column_content_in_char, "%i;%i;%i;%i;%i;%i;%i;%i;%i;%i;%i", &array_number[0], &array_number[1], &array_number[2], &array_number[3], &array_number[4], &array_number[5], &array_number[6], &array_number[7], &array_number[8], &array_number[9], &array_number[10]);
Damit komm ich noch nicht klar. Ich habe mich sehr lange mit stringstreams beschätigt, komme aber dennoch nicht so ganz klar.
Wie muss ich das in C++ machen?
Mfg Flo
-
for(int i = 0; i < 11; ++i) std::cin >> array[i];
-
FlorianB schrieb:
Wie muss ich das in C++ machen?
Hallo Flo,
so wie es hier steht.
314159265358979 schrieb:
for(int i = 0; i < 11; ++i) std::cin >> array[i];
Du hast die ';' in sscanf(column_content_in_char, "%i;%i;%i;%i;%i;%i;%i;%i;%i;%i;%i", .. übersehen
-
Da hast du Recht, sorry.
-
Schau dir mal stringstreams an. Vorgehen in dem Fall:
- leerer ostrignstream
- in einer Schleife die Nummern, jeweils gefolgt von einem ';' in den Stream
- string aus dem stringstream holen.
Also 1:
#include <sstream>
...
in der main:ostringstream content_from_line;
2:
for(int i = 0; i < 11; ++i)
{
content_from_line << line_content_in_char + ";";
}3:
Wie mach ich das?
Zu zwei noch: warum eigentlich die Nummern gefolgt von einem Komma? In line_content_in_char steht zum Beispiel 85;45;26;496;314; drin! Da muss ich doch nicht noch Kommas einfügen! Das macht doch schon die CSV Datei bzw das wird schon mit Kommas ausgelesen.
Das versteh ich nicht ganz.
MfG Flo
-
FlorianB schrieb:
pumuckl schrieb:
Schau dir mal stringstreams an. Vorgehen in dem Fall:
- leerer ostrignstream
- in einer Schleife die Nummern, jeweils gefolgt von einem ';' in den Stream
- string aus dem stringstream holen.
[...]
Das versteh ich nicht ganz.
Hallo Flo,
darauf sollte Dir besser pumuckl selbst antworten.
FlorianB schrieb:
Das einizge was jetzt noch fehlt, ist das hier:
sscanf(column_content_in_char, "%i;%i;%i;%i;%i;%i;%i;%i;%i;%i;%i", &array_number[0], &array_number[1], &array_number[2], &array_number[3], &array_number[4], &array_number[5], &array_number[6], &array_number[7], &array_number[8], &array_number[9], &array_number[10]);
[...]
Wie muss ich das in C++ machen?auf diese Frage präzisiere ich meine Antwort von vorhin [12:18:51 09.03.2011]: das Code-Segment in meinem Beitrag in den Zeilen 19-27 zeigt, wie man das in C++ machen kann (nicht muss). Wobei Du in Zeile 22 den Wert von 'number' in einem Array/Container unter dem Index 'spalte' abspeichern kannst.
Gruß
Werner