C/C++ Thread

Troncoso

VIP Member
well my question is about the general use of the functions scanf(), sscanf(), etc. I just want to know how to remove the null terminator from the character stream after using the function. I've googled it a lot and found either long functions for what should be something simple, and I've found fflush(stdin)....which didn't work for me.

The reason I can't give you a code is because this is a problem in any code that I gather user input and then use it in a loop statement. Is that a better explanation?
 

Cromewell

Administrator
Staff member
And for C++ graphics purposes the only comiler you can use is the turbo C++.
which is a really backward and sucky compiler.
That's not strictly true, you can write OpenGL or DirectX Graphics stuff in any compiler, you just need the right header files.
well my question is about the general use of the functions scanf(), sscanf(), etc. I just want to know how to remove the null terminator from the character stream after using the function. I've googled it a lot and found either long functions for what should be something simple, and I've found fflush(stdin)....which didn't work for me.
fflush is mainly for writing not reading, hence why it doesn't work :) What exactly it does on an input stream is library dependant. Clearing the input buffer is non-standard behaviour.

The null terminator is something that you get when you use %s, %c will not add the null terminator. It should be trival to work around though, is there some reason you don't want it?
 

mihir

VIP Member
That's not strictly true, you can write OpenGL or DirectX Graphics stuff in any compiler, you just need the right header files.
I have used graphics header file even with a gcc compiler but its a long and painful procedure.TC comes built in with it and you just have o adjust the linker settings.In many other compilers you need to put the proper header files but in TC it is already their.If you have proper header files you can use it with any compiler you would just need to set the linker and also copy the appropriate files to appropriate folder
 

Troncoso

VIP Member
That's not strictly true, you can write OpenGL or DirectX Graphics stuff in any compiler, you just need the right header files.

fflush is mainly for writing not reading, hence why it doesn't work :) What exactly it does on an input stream is library dependant. Clearing the input buffer is non-standard behaviour.

The null terminator is something that you get when you use %s, %c will not add the null terminator. It should be trival to work around though, is there some reason you don't want it?


I don't have access to my code in question but this is the psuedo code:

Code:
num1 = *function that uses scanf()*
num2 = *that function again()*

printf("Enter an operation: ");
scanf("%c", input);

while input != aCertainValue
{ printf("error message!!!");
   scanf("%c", input);}

The result is this:

Enter a number: error message!!! _

It prints the prompt but immediately jumps to the loop, putting the null terminator in for input and reads it as invalid and displays the error message. Unless something else is going on.
 

mihir

VIP Member
Problem
It is desirable to have integers that are unlimited in length. But many programming languages have a limited size integer. C language also has the same limitation. The 'int' type has a size of 4 or 8 bytes nowadays. A 4 byte int can store maximum upto 2^32 that is 4294967296. To store higher values, we can create our own datatype called MyInteger.

Suppose we have to store the number 8589934592 (that is 2^33). Then we can store this number by cutting it in multiple parts. For example one way of storing it will be as follows: We store '8' as one digit, '5' as another in 'int's. Then we link up all these ints using a linked list. So in this case, our data type will be

typedef struct node {
int digit;// can be char digit also, but will be more tricky
struct node *next;
}node;
Now using this a list can be created, which can be accessed from the first node. So we can define
typedef struct node *MyInteger;

On this structure we can also define functinos like
MyInteger add(MyInteger p, MyInteger q);
void Read(Myinteger *a);
void print(MyInteger a);

Which can be called by the user as:
main() {
MyInteger a, b, c;
......
read(&a);
read(&b);
c = add(a, b);
print(a);
}


Here a and b are two variables of MyInteger type and they represent two unlimited size integers to the user. The user treats the c = add(a, b) as c = a + b where c, a, b are unlimited size. While implementing the functions, we basically do some linked list manipulation.


one can do the 'split' more carefully for performance. the number 8589934592 can also be split 2 parts only because an 'int' can store upto 2^32 (or 2^31) data. the logic of 'add()' and other functions will also change accordingly. hint: any number can be represented using any base. for example: 123 = 1*10^2 + 2 * 10^1 + 3 * 10^0 spo 123 was represented using base 10. 123 = 1111011 = 1*2^7 + 1*2^6 + 1*2^5 + 1*2^4+ 1 *2^3 + 1 * 2^1 + 1 * 2^0

Assignment
implement an efficient MyInteger type. the type should have following functions:

Myinteger add(Myinteger p, Myinteger q); // adds p and q and returns the addition (as a new list)
Myinteger mult(Myinteger p, Myinteger q); //multiplies integer p and q and returns the result as a new myinteger
Myinteger readmyint();// reads an unlimited size integer from keyboard and returns it.
void print(Myinteger a); // prints a myinteger
Myinteger readfromfile(char *filename); // reads the integer string stored in a file, given as filename, and returns the myinteger created.

for this submit a myinteger.h and myinteger.c files.
write some big integer data in two files (call them one.int and two.int)

write a user program that can be called as follows: (filename: useint.c)
./useint one.int two.int

the program will call the MyInteger functions, add them and print the result of addition and multiplication as a third MyInteger. While printing just print the number, don't print additional stuff like "Myinteger:123412541223".
 

Cromewell

Administrator
Staff member
alright. I'll be able to post my code when I get home. Thanks for the help so far.
That will help a lot. The pseudo code looks like you're doing everything right, which is why I need to see the actual code.
Problem
It is desirable to have integers that are unlimited in length. But many programming languages have a limited size integer. C language also has the same limitation. The 'int' type has a size of 4 or 8 bytes nowadays. A 4 byte int can store maximum upto 2^32 that is 4294967296. To store higher values, we can create our own datatype called MyInteger.

Suppose we have to store the number 8589934592 (that is 2^33). Then we can store this number by cutting it in multiple parts. For example one way of storing it will be as follows: We store '8' as one digit, '5' as another in 'int's. Then we link up all these ints using a linked list. So in this case, our data type will be

typedef struct node {
int digit;// can be char digit also, but will be more tricky
struct node *next;
}node;
Now using this a list can be created, which can be accessed from the first node. So we can define
typedef struct node *MyInteger;

On this structure we can also define functinos like
MyInteger add(MyInteger p, MyInteger q);
void Read(Myinteger *a);
void print(MyInteger a);

Which can be called by the user as:
main() {
MyInteger a, b, c;
......
read(&a);
read(&b);
c = add(a, b);
print(a);
}


Here a and b are two variables of MyInteger type and they represent two unlimited size integers to the user. The user treats the c = add(a, b) as c = a + b where c, a, b are unlimited size. While implementing the functions, we basically do some linked list manipulation.


one can do the 'split' more carefully for performance. the number 8589934592 can also be split 2 parts only because an 'int' can store upto 2^32 (or 2^31) data. the logic of 'add()' and other functions will also change accordingly. hint: any number can be represented using any base. for example: 123 = 1*10^2 + 2 * 10^1 + 3 * 10^0 spo 123 was represented using base 10. 123 = 1111011 = 1*2^7 + 1*2^6 + 1*2^5 + 1*2^4+ 1 *2^3 + 1 * 2^1 + 1 * 2^0

Assignment
implement an efficient MyInteger type. the type should have following functions:

Myinteger add(Myinteger p, Myinteger q); // adds p and q and returns the addition (as a new list)
Myinteger mult(Myinteger p, Myinteger q); //multiplies integer p and q and returns the result as a new myinteger
Myinteger readmyint();// reads an unlimited size integer from keyboard and returns it.
void print(Myinteger a); // prints a myinteger
Myinteger readfromfile(char *filename); // reads the integer string stored in a file, given as filename, and returns the myinteger created.

for this submit a myinteger.h and myinteger.c files.
write some big integer data in two files (call them one.int and two.int)

write a user program that can be called as follows: (filename: useint.c)
./useint one.int two.int

the program will call the MyInteger functions, add them and print the result of addition and multiplication as a third MyInteger. While printing just print the number, don't print additional stuff like "Myinteger:123412541223".
Is this the solution that you were asked to create for this assignment? Doing math on compound fields like that can be tricky. Luckily, addition and multiplication aren't so bad, I did something similar by using a string to store the number instead of chained integers.
 

mihir

VIP Member
That will help a lot. The pseudo code looks like you're doing everything right, which is why I need to see the actual code.

Is this the solution that you were asked to create for this assignment? Doing math on compound fields like that can be tricky. Luckily, addition and multiplication aren't so bad, I did something similar by using a string to store the number instead of chained integers.

I have already done this and got a 10 on 10 in class.This question is for other to try.
Post me your solutions.I will also post mine later when everyone has tried
 

Troncoso

VIP Member
Haha, besides the 3 of us (rather the 2 of you) no one on the forums has expressed enough interest in C to actually post about it. Makes me sad. I'd love to compare and learn from others who are learning the language. As for the problem, while I understand it for the most part, it's still a bit over my head, so I have to pass.
 

Troncoso

VIP Member
Okay this is dumb. I'm having all sorts of trouble with char arrays:

I am making a simple function that takes a string and reverses the characters.

here is the function call:
Code:
char string[256], reverse[256];
printf("This program takes a string and reverses it. So let's go!\n");
printf("Please type a word or phrase: ");
scanf("%s", string);
    
reverse = reverseString(string);

and here is the function (doesn't reverse yet):

Code:
char* reverseString(char[]);

char* reverseString(input[])
{
     char reversed[256];
     int length = strlen(input);
     
     reversed = "yes";
     return reversed;
}

This gives me all kinds of errors involving the prototype declaration, the use of input, and whatnot. So, how do you properly:

pass to a function
define a function
return from a function

using char arrays???
 

Cromewell

Administrator
Staff member
Your mistake is in the function declaration, you are missing the datatype, but there are other problems. You are also getting into pointers here which can be confusing. I need to build a few versions to try and remeber all this, it's been a while for me.
 

Troncoso

VIP Member
actually I just noticed this stupid mistake:

Code:
reversed = "yes";

haha. I know you can't do that.

EDIT: pointers annoy the hell out of me. I just can't understand their usefulness and without that, I can't understand how to use them. Like in my situation, I have no idea how to properly set up a pointer to allow what I'm doing
 
Last edited:

Cromewell

Administrator
Staff member
So one important thing to understand is the way C/C++ treats arrays when you pass them to a function.

With your function: char* reverseString(char input[])
input is actually a pointer to the array you've passed. This means if you do anything to it in the function that change also exists in the 'outside world' so to speak.

Take this trivial example:
Code:
void example(int[]);

void example(int arr[]){
  arr[0] = 5;
}

int main(){
 int array[5] = {1,2,3,4,5};
 //array contains 1,2,3,4,5
 example(array);
 //array now contains 5,2,3,4,5
}

There are easy 2 ways I think you can work your reversing function. 1 is to reverse the string in place the second is to take the return value as a second parameter like:
Code:
void reverseString(char input[], char reversed[])
{
//put your logic here
}
 

brian

VIP Member
Ok so I need to figure out what to use. I want to make an uno isk game such that you will be given a random set of cards with two numbers attached to it, Ie a number from 1-10 (face value) and a number 1-4 (color) I was thinking an array such that each two sets of data would be one card ie x[] = {7,3,6,4} however I want to be able to delete any two values and have them move the whole array down ie from the old example delete the 7,3 card and have the array = {6,4}. Because of that I looked into lists but it also seems a bit too complex for this idea. Any ideas on what I can use. I also want to be able to call the numbers quickly.
 

Cromewell

Administrator
Staff member
strrev isn't a standard function I think that is a Visual C++ bonus function, there is a reverse function but it's a C++ template and works on vectors.

Brian: a 2 dimensional array may work for you if you don't want to use objects.
 

brian

VIP Member
strrev isn't a standard function I think that is a Visual C++ bonus function, there is a reverse function but it's a C++ template and works on vectors.

Brian: a 2 dimensional array may work for you if you don't want to use objects.

How can I delete a value and move the rest down one to fill it in?
 

Cromewell

Administrator
Staff member
If you actually want to resize the array you are looking at malloc calls. From that point of view a linked list is easier but you'll want to watch out for memory leaks.

I suppose you could probably use a place holder array to simplify it and only use a pointer to the start of your array.
 
Top