I'm trying to teach myself C using Kernighan's book and I'm supposed to make a graph that indicates how many letters there are in each word. I haven't got to the "plotting" part as I'm getting really weird and enormous numbers at the output. Right now I'm just trying to have the value of the first and second elements of the array "arreglo" printed.
The code is the following:
#include <stdio.h>
#define ARRAY_SIZE 100
/*#define AUX 0
#define AUX2 0*/
main()
{
int s,j,noletra,i,arreglo[ARRAY_SIZE],otros, nopalabra, c;
int a;
nopalabra=1;
while((c=getchar())!=EOF)
{
if(c==' '||c=='\t'||c=='\n')
++nopalabra;
else
++arreglo[nopalabra];
}
printf("%d",arreglo[1],arreglo[2]);
}
The reason I'm trying to know the value in the second element in the array is that the first element has the correct value. The code is supposed to add 1 to the array index which is the number of words each time a space, tab or \n is typed and to add 1 to the array element whenever something different than the previously mentioned characters is typed (Letters). Right now it´s supposed to print correctly the number of the letters of two words, the first element is correctly printed but the second is a huge number, the output is:
alan amaury
^Z
4 8257542
--------------------------------
Process exited after 7.773 seconds with return value 9
Press any key to continue . . .
The output is supposed to be 4 7. I'm using a compiler in windows so EOF should be Ctrl+Z
Any help that I could get from you will be appreciated :)
At least these problems.
int arreglo[ARRAY_SIZE]; is not initialized before its elements are incremented. This is the mostly likely cause of "Why am I getting this huge numbers" #ikegami
// int arreglo[ARRAY_SIZE];
// replace with
int arreglo[ARRAY_SIZE] = { 0 };
Code can access out of array bounds as nopalabra is not confined to 0 to 99.
#define ARRAY_SIZE 100
int arreglo[ARRAY_SIZE];
++arreglo[nopalabra]; // No access protection
printf("%d",arreglo[1],arreglo[2]); only prints arreglo[1]
Logic flow is incorrect to "make a graph that indicates how many letters there are in each word."
main() return type not coded.
Some pseudo-code as an alternative
int main(void) {
set all arreglo[] to 0
int nopalabra = 0;
part_of_word = false; // Keep track of word state
loop forever {
get a character into c
if c is a separator or EOF
if (part_of_word) {
arreglo[nopalabra]++;
part_of_word = false;
nopalabra = 0;
if (c == EOF) break loop
} else {
nopalabra++;
part_of_word = true;
}
}
print out results
}
First, try the solution answered before, changing the printf() call.
If there is still a problem try:
printf("%d %d \n",arreglo[1],arreglo[2]);
Just before the while loop, to see if the "arreglo" array is initialize to 0's or just random values.
On the side:
Your call to printf() has more parameters than covered by the format string.
So you should clean up your code to something similar to
printf("%d %d\n", arreglo[1], arreglo[2]);
Concerning the strange output:
A way of getting surprising values is using non-initialised variables.
In your case the lack of initialisation affects the array arreglo.
Make sure to initialise it, so that all counting starts on a meaningful value.
Another way of getting seemingly very high values is printing several numbers next to each other, without separating white space in between.
So the " " and the "\n" in the format string I proposed are quite relevant.
the question is: "Why am I getting this huge numbers in C?"
the answer is: you have not assigned anything to arreglo array, and since you have not initialized it, you got some random values that have been there in memory. Trust me on this, I have run your code in debugger, which I also highly recommend a a standard practice while lerning to program.
Also, this is a common mistake where the format specifier is not written:
printf("%d",arreglo[1],arreglo[2]);
See if using printf("%d","%d",arreglo[1],arreglo[2]) solves your problem.
By the way, K&R book is very old, and written at the time where there have been no other C books. There are better ways to learn C.
Related
I am a beginner is Computer Science and I recently started learning the language C.
I was studying the for loop and in the book it was written that even if we replace the initialization;testing;incrementation statement of a for loop by any valid statement the compiler will not show any syntax error.
So now I run the following program:
#include<stdio.h>
int main()
{
int i;
int j;
for(i<4;j=5;j=0)
printf("%d",i);
return 0;
}
I have got the following output.
OUTPUT:
1616161616161616161616161616161616161616.........indefinitely
I understood why this is an indefinite loop but i am unable to understand why my PC is printing this specific output? Is there any way to understand in these above kind of programs what the system will provide us as output?
This is a case of undefined behaviour.
You have declared i so it has a memory address but haven't set the value so its value is just whatever was already in that memory address (in this case 16)
I'd guess if you ran the code multiple times (maybe with restarts between) the outputs would change.
Some more information on uninitialized variables and undefined behaviour: https://www.learncpp.com/cpp-tutorial/uninitialized-variables-and-undefined-behavior/
Looks like i was never initialized, and happens to contain 16, which the for loop is printing continuously. Note that printf does not add a new line automatically. Probably want to read the manual on how to use for.
To better understand what is going on, you can add additional debugging output to see what other variables are set to (don't forget the \n newline!) but really problem is the for loop doesn't seem right. Unless there's something going on with j that you aren't showing us, it really doesn't belong there at all.
You are defining the variable i but never initializing it, instead, you are defining the value for j but never using it.
On a for loop, first you initialize the control variable, if you haven't already done it. Then you specify the condition you use to know if you should run another iteration or not. And last but not least, change the value of the control variable so you won't have infinite loops.
An example:
#include <stdio.h>
int main()
{
// 1. we declare i as an integer starting from 1
// 2. we will keep iterating as long as i is smaller than 10
// 3. at the end of each iteration, we increment it's value by 1
for (int i = 1; i < 10; i++) {
printf("%d\n", i);
}
return 0;
}
Currently, I am experimenting some codes regarding/about random numbers. The problem is, when I run the program, input any number (ex. 12), I, sometimes get the correct and sometimes wrong answer. The correct answer must be any non repeating random numbers based on user input. (ex. input 5, output must be 1. seats[12]=1, 2. seats[19]=1,..., 5. seats[47]=1). I do not know what to do and yeah help me coders!
Here's the code:
#include<stdio.h>
#include<conio.h>
#include<time.h>
main()
{
int x,y,chc1A,seats[50]={};
printf("Enter a number: ");
scanf("%d",&chc1A);
srand(NULL);
for(x=0;x<chc1A;x++)
{
if(seats[rand()%50]==0)
seats[rand()%50]=1;
else
x--;
}
for(x=0,y=1;x<50;x++)
if(seats[x]==1)
{
printf("%d. seats[%d] = %d\n",y,x,seats[x]);
y++;
}
getch();
}
I do not really know what's wrong please enlighten me.
I run and coded this on Dev C++
What I want to do is: generate random numbers between 0-49 and putting it in an array seats[50]. (ex 38 then put 1 in array seats[38]). Btw this code represents passengers sitting on a bus with 50 seats. So the "1" means that the seat is occupied.
This part may cause problem.
for(x=0;x<chc1A;x++)
{
if(seats[rand()%50]==0)
seats[rand()%50]=1;
else
x--;
}
I think by
if(seats[rand()%50]==0)
seats[rand()%50]=1;
you meant to generate a random number, use that as index to seats and if seats[random_no] is 0, set seats[random_no] to 1.
But the random number in the if statement and the one in its body are different numbers.
You could use
int index = rand()%50;
if(seats[index]==0)
seats[index]=1;
Consider changing the signature of your main() function. See What are the valid signatures for C's main() function?
conio.h is not part of the standard, try to avoid its usage. Same goes for getch() as it's from conio.h.
srand() expects an unsigned int as argument and NULL is not of that type. See here.
Include stdlib.h to use srand().
And checking the return value of scanf() is a good idea. You can see if it failed or not.
I got the task in university to realize an input of a maximum of 10 integers, which shall be stored in a one dimensional vector. Afterwards, every integer of the vector needs to be displayed on the display (via printf).
However, I don't know how to check the vector for each number. I thought something along the lines of letting the pointer of the vector run from 0 to 9 and comparing the value of each element with all elements again, but I am sure there is a much smarter way. I don't in any case know how to code this idea since I am new to C.
Here is what I have tried:
#include <stdio.h>
int main(void)
{
int vector[10];
int a;
int b;
int c;
a = 0;
b = 0;
c = 0;
printf("Please input 10 integers.\n\n");
while (a <= 10);
{
for (scanf_s("%lf", &vektor[a]) == 0)
{
printf("This is not an integer. Please try again.\n");
fflush(stdin);
}
a++;
}
for (b <= 10);
{
if (vector[b] != vector[c]);
{
printf("&d", vector[b]);
c++;
}
b++;
}
return 0;
}
Your code has several problems, some syntactic and some semantic. Your compiler will help with many of the former kind, such as
misspelling of variable name vector in one place (though perhaps this was a missed after-the-fact edit), and
incorrect syntax for a for loop
Some compilers will notice that your scanf format is mismatched with the corresponding argument. Also, you might even get a warning that clues you in to the semicolons that are erroneously placed between your loop headers and their intended bodies. I don't know any compiler that would warn you that bad input will cause your input loop to spin indefinitely, however.
But I guess the most significant issue is that the details of your approach to printing only non-duplicate elements simply will not serve. For this purpose, I recommend figuring out how to describe in words how the computer (or a person) should solve the problem before trying to write C code to implement it. These are really two different exercises, especially for someone whose familiarity with C is limited. You can reason about the prose description without being bogged down and distracted by C syntax.
For example, here are some words that might suit:
Consider each element, E, of the array in turn, from first to last.
Check all the elements preceding E in the array for one that contains the same value.
If none of the elements before E contains the same value as E then E contains the first appearance of its value, so print it. Otherwise, E's value was already printed when some previous element was processed, so do not print it again.
Consider the next E, if any (go back to step 1).
I'm fairly new to coding and am currently learning C. In my C programming class, my instructor gave us the assignment of writing a program that uses a function which inputs five integers and prints the largest. The program is fairly simple even for me, but I'm facing some problems and was hoping to get some advice.
#include <stdio.h>
int largest(int x);
int main(void) {
int integer1;
largest(integer1);
return 0;
}
int largest(int x) {
int i;
for (i = 0; i < 5; i++) {
printf("Enter an integer: ");
scanf_s("%d", &x);
}
return x;
}
This is the code that I have written. The main problem that I am having is that in my main method, the IDE tells me to initialize the value of integer1. However, I'm not really sure how to do that because I'm supposed to input the value within the largest() method via the scanf_s function. How may I solve this?
The problem is here, the warning message is to warn you about the potential pitfall of using the value of an uninitialized automatic local variable. You made the call like
largest(integer1);
but you ignore the return value, so the integer1 remains uninitialized.
Remember, in view of largest(), x is a local copy of the actual argument passed to that function, any changes made to x won't be reflecting to the caller.
That said, your code is nowhere near your requirement, sorry to say. A brief idea to get there would be
Create a function.
Create a variable (say, result) and initialize with minimum possible integer value, INT_MIN
Loop over 5 times, take user input, compare to the result value, if entered value found greater, store that into result, continue otherwise.
return result.
I know that normally help for assignments shouldn't be given but I have to say that you might need to rethink what you want to do.
You are inputting an integer to the function named largest. But why are you only inputting a single integer to a function that should return the largest value. You can't do much with a single number in that case.
You should instead be inputting say an array of 5 values(as said in your assignment) to the function and let it return the largest.
The order would then be:
Read 5 values and save to an array
Call the function largest with the array as input
Let the function do it's work and return the largest value
Do what ever you want with the largest value
But if you only want to remove the warning simply type
int integer1 = 0;
I am trying to modify a value in an array using the C programming language and I seem to be hitting a blank wall with this seemingly easy operation. Please see code snippet below:
while(1) {
printf("Current prime candidate is %i\n",nextPrimeCandidate);
int innerSieve;//=2;
int currentPrimeCandidate=0;
for (innerSieve=2;innerSieve<SIEVELIMIT;innerSieve++) {
currentPrimeCandidate = nextPrimeCandidate * innerSieve;
//printf("Inner Sieve is b4 funny place %i,%i\n",innerSieve,currentPrimeCandidate);
//initArray[currentPrimeCandidate]=5;
//VERY UNIQUE LINE
myArray[currentPrimeCandidate] = 0;
//printf("Inner Sieve after funny place is %i,%i \n",innerSieve,currentPrimeCandidate);
}
nextPrimeCandidate=getNextPrimeCandidate(myArray,++nextPrimeCandidate);
if ((nextPrimeCandidate^2) > SIEVELIMIT ) break;
}
The problem is with the line highlighted with the VERY UNIQUE LINE comment. For some reason, when the innerSieve variable reaches 33 and gets to that line, it sets the contents of the innerSieve variable to the value of that line ( which currently is 0) and basically forces the loop into an infinite loop( the SIEVELIMIT variable is set at 50). It seems that there is some funny stuff going on in the registers when I checked using the Eclipse Debug facility but I am not too sure what I should be looking for.
If you need the whole code listing, this can be provided.( with a particular variable which is not yet initialised in the code being initialised at the precise point that the innerSieve variable hits 32)
Any help will be greatly appreciated.
Guessing that currentPrimeCandidate is greater than the maximum index of myArray, and you're overwriting innerSieve (which likely follows myArray on the stack).
#ruslik hit on it in the comment. The problem is this line:
if ((nextPrimeCandidate^2) > SIEVELIMIT ) break;
In C, the ^ operator is not the power operator, it is the bitwise xor operator. You're iterating far too many times than you intend, which is resulting in an array-index-out-of-bounds error, so you're overwriting random memory and getting strange results.
There is no power operator in C (though there is the pow function). Since you're just squaring a number, the simplest fix is to multiply the number by itself:
if ((nextPrimeCandidate * nextPrimeCandidate) > SIEVELIMIT ) break;