Reading large integers into linked list

I have a large integer , 234321, stored in a text file, input.txt. I want to read it, digit by digit, then insert into a linked list. This doesn't work, I know it has something to do with my while loop in main, how can I fix this?
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
64
65
66
67
68
69
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;

struct Node{
    int data;
    Node *next;
};

Node *createNode(int n){
    Node *newNode;
    newNode=(Node*)malloc(sizeof(Node));

    newNode->data=n;
    newNode->next=NULL;
return newNode;
}

Node *insertAtHead(Node *top, int n){
    Node *newNode;
    newNode = createNode(n);
    newNode->next = top;
    top=newNode;
return top;
}

void printList(Node *top){
    Node *curr;
    int count=0;
    if(top==NULL){
        cout<<"List is empty"<<endl;
        return;
    }
    curr=top;
        while(curr!=NULL){
            cout<<curr->data<<" ";
            curr=curr->next;
        }
        cout<<endl;
}

int main(){
ifstream in;
ofstream out;
Node *top;
top=NULL;
long long int num1=0;
long long int num2=0;
int digit=0;
int counter=0;
in.open("input.txt");
out.open("output.txt");
    if(!in.is_open()){
        cout<<"Error opening file..."<<endl;
    }
    in>>num1;
      while(num1!='\n'){
        if((num1>=0)&&(num1<10))
                top=insertAtHead(top, num1);
            else {
                digit=num1%10;
                top=insertAtHead(top, digit);
                num1=num1/10;
            }
      }
printList(top);
return 0;
}
we can fix it, but the approach is probably wrong.
read the number one character at a time and insert those into the list.
that is, instead of having int num1 that you read from the file, read char c1 instead and insert that as a digit (you probably want c1-'0' not c1, that is you want 0 not '0' the character right?)

that's right, only numbers. So far I've done this, but I still get no result. What would the proper while condition be in this case?
1
2
3
4
5
6
in>>c1;
    while((c1!=' ')|| (c1!='\n')){
        c1=c1-'0';
        insertAtHead(top, c1);
        in>>c1;
    }


Last edited on
not sure, it depends on your file structure, but I would think

do //assuming you know you are now at a point to expect a number...
cin >> c1;
... things
while(isdigit(c1));


consider using new instead of malloc. Malloc is C and its a little more clunky to use it. It does have an advantage because of realloc, but c++ vectors and containers generally have that covered so you don't have to fool with it.

Last edited on
Node logic seems good, but a few notes:
- Consistency: if start of list is called Head, call it that throughout (rename 'top')
- Parallelism: destroy the things you create (in this case missing frees)
- C++: compare pointers to nullptr instead of NULL. Prefer new and delete to malloc/free. (Nitpick) A lot of your methods are named in the Java style of lower case letter first -- you either want snake_case_methods or CamelCaseMethods.

Did a brief refactor with example cleanup method here: https://repl.it/repls/GlaringVividBsddaemon

(Didn't look at your file issue yet)
actually we are thinking too hard just do this

while(in >> c1)
{

top=insertAtHead(top, c1-'0');

}

I spent a min looking for trouble in the linked list (none!) and not enough looking at your file handling (the actual issue).
Last edited on
I'd do a single read to seed the linked list with the first number, and then do the loop for the remaining ones, to avoid having a bunch of numbers and then a null item.

Without the extra division/modulo logic you have, simple example, as in updated version https://repl.it/repls/FluffySoupyBruteforceprogramming:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
    const char* data_text = R"LITERAL(
42 0 1 2 3 4 5
)LITERAL";

    // Imitate file stream
    istringstream iss(data_text);
    
    int data;
    iss >> data;
    Node* root = CreateNode(data);
    for ( ; iss>>data; )
    {
        root = InsertAtHead(root, data);
    }
    PrintList(root);
    CleanList(root);
    PrintList(root);
    return 0;
}


ifstream instead of istringstream would be basically what you have. Just do !ifs to see if anything went wrong:

1
2
3
4
5
6
ifstream ifs("input.txt");
if (!ifs)
{
    cout << "Error opening file..." << endl;
    return -1;
}


Rest should be pretty much exactly like the istringstream.

The formatted read with ifs>>data should by default skip past spaces and newlines.
Topic archived. No new replies allowed.