znak konca linii w odczycie z pliku

0

mam plik wejściowy który wygląda następująco:

| 1: 2 23 3 12 3 3 43 55 23 8   |
| 2: 1 13     |
| 3: 126      |
| ...  ...      |
| V: E1 E2 ... |
 
mam problem z odczytaniem znaku końca linii - chciałabym żeby po jego odczytaniu kolejny wiersz pliku zostawał odczytywany ponownie od miejsca oznaczonego <--

#include <iostream>
#include <fstream>
using namespace std;
#define MAX 10000
int main()
{

    fstream plik( "dane.txt" );
    int V;
    char dwukropek;
    int E;
    string linia;

    if( plik )
    {
        while( !plik.eof() )
        {

            plik >> V; // <-----
            cout<<"V: "<<V<<endl;
            plik >> dwukropek;
            cout<<dwukropek<<endl;

            char a;
                while(a!='\n' || a!='\r\n' || a!='0x0D' || a!='0x0A') // 1
                {
            plik>>E;
            mac_sas[ V ][ E ] = 1;
            cout<<"E: "<<E<<endl;
            char a;
            plik.get(a);

             }

        }

    }

    else
    {
        cout << "blad oczytu" << endl;

    }
}
0

To co widać na pierwszy rzut oka, to

char a; // niezainicjalizowana zmienna
                while(a!='\n' || a!='\r\n' || a!='0x0D' || a!='0x0A') // tutaj jej używasz co jest UB, warunek też nie ma sensu
                {
            plik>>E;
            mac_sas[ V ][ E ] = 1; // no i tutaj deklaracja tablicy jest nieprawidłowa

Tablice dynamiczne mają rozmiar ustalany w czasie działania programu, a tutaj rozmiar musi być constexpr (skorzystaj z std::vector).
W C++ nie ma VLA.
Warunek zawsze będzie prawdziwy (pętla nieskończona).

Dane z pliku czytaj do std::string i później wczytany wiersz analizuj std::ostringstreamem znak po znaku.

0

Tworzysz zmienną a, nie przypisujesz jej jakiekolwiek wartości, jest niezainicjalizowana.
Następnie w while porównujesz czy a jest równe z \n itd. No ale jak, skoro a nie ma żadnej wartości?

Mam nadzieję, że wiesz, że warunki w while są bezsensowne:

  1. \n to to samo co 0x0A i tak samo \r to to samo co 0x0D
  2. char jak sama nazwa wskazuje to pojedynczy znak. \r\n to dwa znaki.

A teraz działanie twojej pętli.
Aby while się wykonało, warunek musi być TRUE, to wiadome. Ale w tym kodzie sprawdzasz czy jakakolwiek część zwraca TRUE. Czyli, aby wyjść z pętli musiałbyś dostać znak który spełniałby wszystkie warunki, co oczywiście jest niewykonalne.

Co innego gdyby while wyglądał tak:

while(a != '\r' && a != '\n') { }

bo wtedy gdy któraś część będzie FALSE to cały warunek będzie FALSE co spowoduje wyjście z pętli.

Problem może również nastąpić gdy w pliku będzie \r i \n bo może się okazać, że czytasz złą wartość i dostajesz dziwne wyniki.
Napisz coś więcej o programie, bo jestem pewien, że da się lepiej napisać ten kod.

0

Cały kod, z uwzględnionymi uwagami. Program tworzy macierz sąsiedztwa na podstawie listy incydencji odczytując z pliku V jako wierzchołek i E jako wierzchołki incydentne do V - w każdej linii jest inna ilość liczb E (które są 1,2 lub 3 cyfrowe)

#include <iostream>
#include <fstream>
using namespace std;
#define MAX 10000
int main()
{
    // ------------------- tablica wypelniona zerami ---
    int ** mac_sas = new int *[ MAX ];
    for( int i = 0; i < MAX; i++ )
    {
        mac_sas[ i ] = new int[ MAX ];
    }
    for( int i = 0; i < MAX; i++ )
    {
        for( int j = 0; j < MAX; j++ )
        {
            mac_sas[ i ][ j ] = 0;
        }
    }
    // -------------------------------------------------
    fstream plik( "dane.txt" );

    int V;
    char dwukropek;
    int E;
    string linia;

    if( plik )
    {
        while( !plik.eof() )
        {

            plik >> V;
            cout<<"V: "<<V<<endl;
            plik >> dwukropek;
            cout<<dwukropek<<endl;

            char a;
                do 
                {
            plik>>E;
            mac_sas[ V ][ E ] = 1;
            cout<<"E: "<<E<<endl;
            char a;
            plik.get(a);

             }while(a!='\n' && a!='\r' );

        }
//---------------- testy
        cout<<mac_sas[1][1]<<endl;
        cout<<mac_sas[1][2]<<endl;
        cout<<mac_sas[0][0]<<endl;
// ---------------------
    }

    else
    {
        cout << "blad oczytu" << endl;

    }
}
0

https://4programmers.net/Forum/C_i_C++/289441-pobieranie_danych_z_pliku?p=1359589#id1359589

Dostosowując do twojego formatu pliku

auto ReadMatrix(istream& stream) -> std::vector<std::vector<int>>
{
  std::vector<std::vector<int>> data;
  std::string line;
  while (std::getline(stream, line)) {
    std::vector<int> rowData;
    std::istringstream rowStream { line };
    int x;
    string dummy;
    getline(rowStream, dummy, ':');
    while (rowStream >> x)
    {
       rowData.push_back(x);
    }
    data.push_back(std::move(rowData));
  }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1