I'm trying to count the characters, words, lines an paragraphs in C from the stdin.
something is not working and I don't know why.
#include <stdio.h>
int main(int argc, char const *argv[])
{
int pCount=0, parCount=0, cCount=0, lCount=0;
double prom=0;
char c;
int newln_cnt=0;
while ((c=getchar())!=EOF){
cCount++;
switch (c)
{
case '\n':
newln_cnt++;
lCount++;
if (newln_cnt == 2)
{
parCount++;
newln_cnt = 0;
}
break;
case ' ':
pCount++;
break;
}
}
prom = (cCount / pCount);
printf("Total caracteres: %d \n", cCount);
printf("Cantidad palabras: %d \n", pCount);
printf("Cantidad líneas: %d \n", lCount);
printf("Cantidad párrafos: %d \n", parCount);
printf("Promedio longitud palabra: %f \n", prom);
return 0;
}
it kinda works with the characters (it shows one less). but the rest is all bad.
Input:
Oid, mortales, el grito sagrado:
"Libertad, libertad, libertad!"
Oid el ruido de rotas cadenas,
ved en trono a la noble igualdad.
Ya su trono dignisimo abrieron
las Provincias Unidas del Sud
y los libres del mundo responden:
"Al gran pueblo argentino, salud!
Al gran pueblo argentino, salud!"
Y los libres del mundo responden:
"Al gran pueblo argentino, salud!"
Sean eternos los laureles
que supimos conseguir,
que supimos conseguir.
Coronados de gloria vivamos...
o juremos con gloria morir!,
o juremos con gloria morir!,
o juremos con gloria morir!
Expected Ouput:
Total caracteres: 558
Cantidad palabras: 87
Cantidad líneas: 25
Cantidad párrafos: 8
Promedio longitud palabra: 4.966
my ouput:
Total caracteres: 557
Cantidad palabras: 69
Cantidad líneas: 24
Cantidad párrafos: 12
Promedio longitud palabra: 8.000
The program counts the number of characters, words, lines and paragraphs (two consecutive '\n'). and the averge word length .
Each your count conditions are wrong.
fix like follows:
#include <stdio.h>
#include <ctype.h>
int main(void){
int pCount=0, parCount=0, cCount=0, lCount=0;//word, paragraph, character, line
int abCount = 0;//alphabet
double prom=0;
int c;//It should be int.
char pprev = '\n', prev = '\n';
while ((c=getchar())!=EOF){
++cCount;
if(isalpha(c))
++abCount;
if(isspace(c)){
if(c == '\n'){
++lCount;
}
} else if(isspace(prev)){//isspace(prev) && !isspace(c) : edge of top of word
++pCount;
if(pprev == '\n' && prev == '\n'){//edge of top of paragraph
++parCount;
}
}
pprev = prev;
prev = c;
}
if(prev != '\n'){//If the file is not terminated by newline
++lCount;
}
prom = (double)abCount / pCount;//(cCount - spcCount - punctCount) / pCount
printf("Total caracteres: %d \n", cCount);
printf("Cantidad palabras: %d \n", pCount);
printf("Cantidad lineas: %d \n", lCount);
printf("Cantidad parrafos: %d \n", parCount);
printf("Promedio longitud palabra: %.3f \n", prom);
return 0;
}
I see several problem in your code:
Paragraphs count: you do not set newln_cnt to 0 if read character is different of \n. This will count one paragraph each time two \n are read.
Spaces count: you only consider ' ' characters, you may miss other white space characters like \t ou non breakable space. consider using isspace() function.
Mean line length: you divide two integers to get a float, consider casting:
prom = (float)cCount / (flao)pCount;
My advice: Start with a short text (3 words per line, 5 lines) and a debugger.
It didn't compile because of type conversion errors, but you can use floats for everything and it will compile:
#include <stdio.h>
int main(int argc, char const *argv[])
{
double pCount=0, parCount=0, cCount=0, lCount=0;
double prom=0;
char c;
int newln_cnt=0;
while ((c=getchar())!=EOF){
switch (c)
{
case '\n':
newln_cnt++;
lCount++;
if (newln_cnt == 2)
{
parCount++;
newln_cnt = 0;
}
break;
case ' ':
pCount++;
break;
}
}
prom = (cCount / pCount);
printf("Total caracteres: %f \n", cCount);
printf("Cantidad palabras: %f \n", pCount);
printf("Cantidad líneas: %f \n", lCount);
printf("Cantidad párrafos: %f \n", parCount);
printf("Promedio longitud palabra: %f \n", prom);
return 0;
}
Now that the program compiles, you can adjust to whatever types are best for you program, you might even have a type of your own.
A famous program that works like your program is wc - word count and is part of the standard Unix libraries.
Related
I was tasked to do a program to read the name of one student, 4 of their subjects and their respective grades. I have worked with for and while loops, also with if statements and here is my code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main() {
printf("Este programa captura el nombre de un alumno \n");
printf ("y cuatro de sus materias y sus respectivas notas\n");
printf ("Nota: El programa solo toma en cuenta los dos primeros\n");
printf ("decimales de la notas expresada.\n\n");
char alumno[40] = {'\0'};
char mat[4][20] = {'\0', '\0', '\0', '\0'};
float calif[4] = {-1, -1, -1, -1};
int i;
while (alumno[0] == '\0') {
printf("Ingresa el nombre del alumno: ");
gets(alumno);
if (alumno[0] == '\0') {
printf("\nError. El alumno debe de llevar un nombre.");
printf ("\nTrata nuevamente\n\n");
};
};
for (i = 0; i < 4; ++i) {
while (mat[i][0] == '\0') {
printf("Ingresa el nombre de la materia %d: ", i+1);
gets(mat[i]);
if (mat[i][0] == '\0') {
printf("\nError. Las materias deben ser declaradas.");
printf ("\nTrata nuevamente.\n\n");
};
};
while (calif[i] < 0 || calif[i] > 10) {
printf("Ingrese la nota correspondiente a esta materia (0-10): ");
scanf("%2.2f", calif[i]);
if (calif[i] < 0 || calif[i] > 10) {
printf("\nError. Debe ingresar una nota válidad entre 0 y 10.");
printf ("\nTrata nuevamente.\n\n");
};
};
};
return 0;
};
The program seems to be working fine until it gets to the point to ask the grade of the first subject. Any grade I put it causes an infinite loop. I have searched about this problem to no avail. So please, let me know what I am doing wrong here.
There are multiple problems in your code:
[major] you read the mark with scanf("%2.2f", calif[i]): the format string is incorrect, the first 2 means read at most 2 bytes and the .2 is an error as scanf() does not support the precision syntax at all. It should just be "%f" and you should pass the address of the destination variable &calif[i] instead of its value. Furthermore, you should test the return value to check for invalid or missing input.
the prototype for main is int main(), int main(void) or int main(int argc, char *argv[]), the missing return type is an obsolete syntax.
reading input with gets() is risky as there is no way to prevent buffer overflow with sufficiently long input strings. You should instead use scanf("%39s", alumno) or fgets(alumno, sizeof alumno, stdin) and test the return value to detect premature end of input stream. Same remark for the second instance of gets().
After compiling this program with GCC (Linux or Windows or online test compiler), it fails in different ways each time it runs. I don't understand where I made the mistake.
On Ubuntu Linux, the program crashes without printing an answer.
On Windows 10 (MSYS), it loops indefinitely without printing any message.
On an online compiler I tried, it fails with a segmentation fault (and core dump and exit code 139).
Here is the code:
#include <stdio.h>
int main() {
float riga[1][3];
int ciclo = 2;
int calcolo;
float totale;
int codice = 0;
int quanti = 1;
int prezzo = 2;
printf("\n Inserendo una quantita pari a 0 si conclude con il totale");
do {
codice++;
printf("\n Numero: %d Inserire la quantita:", codice);
scanf("%f", &riga[codice][quanti]);
if ( riga[codice][quanti] < 1 ){
printf("\n Calcolo del totale.");
ciclo = 1;
} else {
printf("\n Numero: %d Inserire il prezzo:", codice);
scanf("%f", &riga[codice][prezzo]);
}
//printf("\n Quantita: %f Prezzo: %f", riga[codice -1][quanti], riga[codice -1 ][prezzo]);
//printf("\n Ciclo = %d", ciclo);
} while( ciclo != 1 );
printf("\n Totale in calcolo");
for ( calcolo = 1; calcolo < (codice + 1); calcolo++){
//printf("\n Prezzo = %f",riga[calcolo][prezzo] );
totale = totale + (riga[calcolo][prezzo] * riga[calcolo][quanti]);
}
printf("\n Totale: %f", totale);
return 0;
}
What is wrong with it?
1.don't use uninitialized variables and you should initialize totale.
2.don't pass boundaries of your array or it will cause undefined behavior.
here in this declaration float riga[1][3]; ,first dimension has only one element.Your increment here codice++; is invalid you don't have riga[1][num] you only have riga[0][num].So remove this line codice++; and also check in your while condition that you won't scan more than 3 elements for second dimension of array.
here
for ( calcolo = 1; calcolo < (codice + 1); calcolo++){
totale = totale + (riga[calcolo][prezzo] * riga[calcolo][quanti]);
}
again you are passing boundaries of array. calcolo could only be zero.
as #John Bollinger said underlying point about arrays: they are indexed from 0, not from 1.
Here is the code, basically I gotta do the ceasar cipher in C using arrays and chars only, here is what I have so far:
#include <stdio.h>
#include <stdlib.h>
main ()
{
char alfabeto[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int a=0;
int b=0;
int m=0;
int c=0;
//char letra;
int cont=0;
char k[]={};
printf("Introduzca un primer numero 'a':\n");
scanf(" %i", &a);
printf("Introduzca un segundo numero 'b':\n");
scanf(" %i", &b);
printf("Introduzca una palabra clave entre 4 y 10 letras (cuando termine presione '.'):\n");
//Falta una validacion para la palabra.
for (int j=0;j<10;j++)
{
scanf(" %c",&k[j]);
cont=j; //cuenta la cantidad de elementos
if (k[j]=='.')
{
j=10;
}
}
for(int j=0;j<cont;j++) //Error in this bit I think.
{
for (int i=0;i<26;i++)
{
if (alfabeto[i]==k[j])
{
m=i;
i=26;
}
}
c = ( (a * m) + b );
printf("%c es: %i \t",k[j],c);
}
}
It uses a formula where c=(a*m+b).
m being the position of the original letter for example: A=0 then m=0.
a being a number you choose as well as b.
In my case I chose a=1 and b=3 and the word CESAR as the key word.
According to the formula the output number of each letter should be c.
The output should be:
C es: 5 E es: 7 S es: 21 A es: 3 R es: 20
Yet it is this:
WrongOutput
UPDATE:
I had to correct this:
char k[]={};
Into this:
char k[10]={'\0'};
Now I get the right output:
Right Output
I want to read some number from the terminal and print them afterwards.
However, they all seem to be some kind of random value instead of the one I supplied.
Why doesn't my input get saved correctly?
int main (void)
{
int i = 0 , numeros[21] , cont = 1, z = 0;
puts("\n === Bienvenido ===\n");
puts("\n === Vamos a procesadar un numero de serie de 20 digitos [Numericos] ===\n");
puts("\n === Dime los numeros ===\n");
while (cont != 20 )
{
fflush(stdin);
scanf("%d", &numeros[i]);
printf("\n === Dime otro numero. Numeros: %d ===\n", cont);
cont++;
}
for (z = 0; z < 20; z++)
{
printf("\nLos numeros son: %d\n", numeros[z]);
}
system("pause");
}
Ok, a couple of issues:
numeros is declared as an array of 21 ints, but you're using it as if it were numeros[20]
Undefined behaviour because you're calling fflush on stdin
scanf("%d", &numeros[i]), though unsafe, is all fine and dandy, but i is never incremented
Check return values of functions... always: scanf returns the number of values it scanned, if it returns 0, no %d was scanned, and numeros[i] needs to be reassigned.
Here's an example of how I'd write your program:
#include <stdio.h>
#include <stdlib.h>
int main ( void )
{
int c,i=0,
numbers[20],
count=0;
//puts adds new line
puts("enter 20 numbers");
while(count < 20)
{
c = scanf(" %d", &numbers[i]);//note the format: "<space>%d"
if (c)
{//c is 1 if a number was read
++i;//increment i,
++count;//and increment count
}
//clear stdin, any trailing chars should be ignored
while ((c = getc(stdin)) != '\n' && c != EOF)
;
}
for (i=0;i<count;++i)
printf("Number %d: %d\n", i+1, numbers[i]);
return 0;
}
You are not incrementing i in the first loop.
You are incrementing cont, but using numeros[i] to store your input. As i never changes, you only write to the first array element. Change the i to cont, as in
scanf("%d", &numeros[cont]);
What exactly do you want to achieve? I see that you're putting into i=0 index of your numeros array number from stdin. Then you're iterating trough this array, but you've just entered one number! You should propbably change the subsctript of your numeros array to cont like that:
scanf("%d", &numeros[cont]);
scanf("%d", &numeros[i]);
should be replaced with
scanf("%d", &numeros[cont]);
AS you are incrementing cont not i
Hello I have a litlle problem. I trying to make a bank wait time program but the time i read a 0 value with scanf() it do not read or read wrong. I did some search but noting that solves my problem.
this is the code.. its in C language.
#include <stdio.h>
int main(){
int c, n, t,i,d;//entradas do usuário (caixas, usuários, momento de chegada, tempo de atendimento
int menor_espera=0;// caixa de menor tempo de espera
int tempo_maximo = 20;// tempo maximo de espera por atencimento
int resultado=0;//Numero de pessoas com mais de 20 minutos de espera por atendimento
scanf(" %u %u %*c\n", &c, &n);// Lê o numero de caixas, numero de clientes no dia
if(c>0 && n>0){//iniciação só com valores positivos e possiveis c>1, n>1 (1 caixa e um cliente)
int caixa[c];// declara o um vetor de caixas
for(i=0;i<n;i++){// Loop de numero de usuários
scanf(" %u %u %*c\n", &t, &d);//Lê um cliente (T e D)
printf("print: %u %u\n", c, n);
int j;
for(j=0; j<c;j++){// loop de caixas
if(caixa[j]<caixa[menor_espera]){//chaca se o caixa atual é o primeiro caixa disponivel (caixa com menos tempo de uso)
menor_espera = j;//positivo, atualiza o caixa de menor espera
}
}if(caixa[menor_espera]-t>tempo_maximo){//checa se o cliente terá de esperar mais que o tempo maximo para ser atendido baseado na sua chegada
resultado++;//positivo, atualiza o contador de usuário que esperaram mais que o tempo maximo
}caixa[menor_espera] += d;// atualiza o tempo de uso do caixa que foi utilizado
}
printf("Resultado final: %d\n", resultado);// exibe resultado final
}getch();
}
and this is a input
1 16
0 10
0 10
0 10
3 10
5 10
7 10
11 10
13 10
14 10
15 10
16 10
17 10
18 3
19 10
20 10
23 3
that's the output i have
print: 10 0
print: 0 0
print: 0 3
print: 0 5
print: 0 7
print: 0 11
print: 0 13
print: 0 14
print: 0 15
print: 0 16
print: 0 17
print: 0 18
print: 19 10
print: 0 10
print: 3 3
print: 3 3
Resultado final: 16
but it shoud'nt look like this.
Tks for any help. if i found the solution i'll post here.
One issue is that you are not capturing or testing the return value from scanf(). It returns the number of items it parsed, or -1 on an i/o error.
Consider something like this to at least find out if this might be a problem:
if (scanf(" %u %u %*c\n", &t, &d) < 2) //Lê um cliente (T e D)
printf ("input conversion or i/o error\n");
This is problematic:
scanf(" %u %u %*c\n", &c, &n);
It looks for two numbers, some white space, and a non-white space character that is ignored, followed by more white space (which may or may not be a newline).
Given your input file, the first scanf() reads:
1 16
0
The next character to be read will be the 1 of the 10 on the second line of data. That's why you have problems.
Use fgets() to read a line at a time, and sscanf() to parse the line. And test the results of both fgets() and sscanf() (or scanf() if you insist on using it).
Here's an approximation to what you need.
#include <stdio.h>
int main(void)
{
int c, n, t,d;
int menor_espera = 0;
int tempo_maximo = 20;
int resultado = 0;
char line[4096];
if (fgets(line, sizeof(line), stdin) != 0)
{
if (sscanf(line, "%u %u", &c, &n) != 2)
return(1);
if (c > 0 && n > 0)
{
int caixa[c]; // VLA - uninitialized
for (int i = 0;i < n; i++)
{
if (fgets(line, sizeof(line), stdin) == 0)
break; // EOF or error
if (scanf(line, "%u %u", &t, &d) != 2)
break; // EOF or error
printf("print: %u %u\n", c, n); // Not t and d??
for (int j = 0; j < c; j++)
{
// Accessing uninitialized data in caixa array!
if (caixa[j] < caixa[menor_espera])
menor_espera = j;
}
if (caixa[menor_espera] - t > tempo_maximo)
resultado++;
caixa[menor_espera] += d;
}
printf("Resultado final: %d\n", resultado);
}
}
return(0);
}
I think there are some logic errors in the original code (some highlighted with comments), but I'm not sure what the corrections should be.