Program not running because of "underscore" - c

I made a program to print an ASCII table up to a certain range (like ASCII from 0 to 104).
#include <stdio.h>
int main(void)
{
int n;
printf("\n\nthis program will print list of ASCII values for your computer enter the upper limit for the range - ");
scanf("%d", &n);
printf("\nDECIMAL\tCHARACTER");
for (int i = 0; i <= n; i++)
{
printf("\n %d | %c", i, i);
// printf("\n-------------");
printf("_"); //when i include this "undescore" it causes problems, the code stops at 27th ASCII character and gets stuck.
}
return 0;
}
The 27 decimal corresponds to ASCII SYSTEM CODE - [ESCAPE].
None of the following works, and the code stops at the 27th ASCII character:
printf("__"); //double or multiple underscore does not work.
printf("\n_"); //this doesnt work either.
printf("//_"); //somehow this works.
If I remove that printf("_"); part then the code does not stop at 27 and runs smoothly, the code only stops when I use the underscore (_) character.
If I use a different character (-, *, etc), it runs smoothly.
What can the problem be? Could it be something related to macros?
Edit-
when I replaced 'printf("_");' with 'printf("n");' thinking it would perform the same as '\n' some weird language popped up and the language of the terminal changed.
when '_' is replaced by 'n'

Your terminal support ANSI escape sequences which means it does something with ESC _: Application Program Command. In general, if your printing it, you probably want to make sure it shows up so I am using an alternative format here for non-printable characters:
#include <ctype.h>
#include <stdio.h>
int main(void) {
printf("\n\nthis program will print list of ASCII values for your computer enter the upper limit for the range - ");
int n;
scanf("%d", &n);
printf("\nDECIMAL\tCHARACTER");
for (int i = 0; i <= n; i++) {
if(isprint(i))
printf("\n %d | %c", i, i);
else
printf("\n %d | 0x%x", i, i);
printf("_");
}
}
Here is a sample output:
this program will print list of ASCII values for your computer enter the upper limit for the range - 38
DECIMAL CHARACTER
0 | 0x0_
1 | 0x1_
2 | 0x2_
3 | 0x3_
4 | 0x4_
5 | 0x5_
6 | 0x6_
7 | 0x7_
8 | 0x8_
9 | 0x9_
10 | 0xa_
11 | 0xb_
12 | 0xc_
13 | 0xd_
14 | 0xe_
15 | 0xf_
16 | 0x10_
17 | 0x11_
18 | 0x12_
19 | 0x13_
20 | 0x14_
21 | 0x15_
22 | 0x16_
23 | 0x17_
24 | 0x18_
25 | 0x19_
26 | 0x1a_
27 | 0x1b_
28 | 0x1c_
29 | 0x1d_
30 | 0x1e_
31 | 0x1f_
32 | _
33 | !_
34 | "_
35 | #_
36 | $_
37 | %_

Related

Why my table is not displayed if I do not put it [i]

I would like to know what the [i] is for, and why my table is not displayed if I do not put it in.
Thank you!
#include <stdio.h>
void affiche(int* tableau, int taille);
int main()
{
int tableau[5] = { 12,15,50,20 };
affiche(tableau, 4);
return 0;
}
void affiche(int *tableau,int taille)
{
int i;
for (i = 0; i < taille; i++)`
{
printf("%d\n", tableau[i]);
}
}
[i] is the C language syntax for array notation.
tableau is an array of 5 integers.
int tableau[5] = {12,15,50,20}
In memory tableau has 5 slots allocated to it due to the above declaration.
Slots 0 through 3 are your initialization values.
Slot 4 is uninitialized (though modern c compilers might set this value to null or zero (0).
tableau
+-----------------------+
index | 0 | 1 | 2 | 3 | 4 |
+-----------------------+
value | 12 | 15 | 50 | 20 | ? |
+-----------------------+
inside function affiche(...) this statement
printf("%d\n", tableau)
tries to print to console a single integer (%d) followed by a newline (\n)
But tableau is an array of 5 integers.
So you need the array index to select a specific integer individually like this:
printf("%d\n", tableau[0]) // output: 12
printf("%d\n", tableau[1]) // output: 15
printf("%d\n", tableau[2]) // output: 50
printf("%d\n", tableau[3]) // output: 20
printf("%d\n", tableau[4]) // output: unknown, possible exception
or by function call to affiche(tableau, 4); which ends at index 3
void affiche( int *tableau, int taille)
{
int i;
for( i = 0; i < taille; i++){
printf( "%d\n", tableau[i] );
}
}
Which outputs:
12
15
50
20

How to group rows with the same column value into one row in C?

I am trying to make a statistic calculation code where a file with years are given on column1, type is given on column2 and count is given for column3. And finding the sum of counts for each type for each year.
I am stuck on grouping my data with same value in the column to be in the same row..
Input data:
2010 101 22
2010 101 40
2010 101 44
2010 101 66
2010 102 14
2010 100 7
2010 101 2
2010 101 3
2010 101 2
2010 101 3
2011 101 23
2011 101 27
2011 101 47
2011 101 66
2011 100 5
2011 102 16
2011 101 4
2011 101 1
2011 101 3
2011 101 5
Output:
| Year | 100 | 101 | 102 |
--------------------------
| 2010 | 7 | 182 | 14 |
| 2011 | 5 | 176 | 16 |
I could do
if(year == 2010)
{}
if(year == 2011)
{}
but my data is not going to always be like the given input. Is there a way to group them without knowing how many rows and what is going to be given in the year column? Maybe comparing row by row?
I'm confused, please help..
With a fixed/limited range for years and types, we can used a fixed size 2D array to hold the counts.
Here's some code that does that:
#include <stdio.h>
#include <stdlib.h>
// year config
#define YRLO 2008
#define YRHI 2020
#define YRTOT ((YRHI - YRLO) + 1)
// type config
#define TYPLO 100
#define TYPHI 103
#define TYPTOT ((TYPHI - TYPLO) + 1)
#define RANGE(_val,_lo,_hi) \
((_val) >= (_lo)) && ((_val) <= (_hi))
int counts[YRTOT][TYPTOT];
int
main(void)
{
const char *file = "data.txt";
FILE *xfin = fopen(file,"r");
if (xfin == NULL) {
perror(file);
exit(1);
}
int yr;
int typ;
int cnt;
int lno = 0;
while (fscanf(xfin,"%d %d %d",&yr,&typ,&cnt) == 3) {
++lno;
if (! RANGE(yr,YRLO,YRHI)) {
printf("line %d -- bad year -- %d\n",lno,yr);
continue;
}
if (! RANGE(typ,TYPLO,TYPHI)) {
printf("line %d -- bad type -- %d\n",lno,typ);
continue;
}
// store data (convert absolute years and types to relative numbers)
counts[yr - YRLO][typ - TYPLO] += cnt;
}
fclose(xfin);
const char *fmt = " | %8d";
int totlen = 0;
// print the title
totlen += printf("| Year");
for (int tidx = 0; tidx < TYPTOT; ++tidx)
totlen += printf(fmt,tidx + TYPLO);
totlen += printf(" |");
printf("\n");
// print a dashed line
for (int icol = 0; icol < totlen; ++icol)
fputc('-',stdout);
printf("\n");
for (int yidx = 0; yidx < YRTOT; ++yidx) {
// A nicety: decide if year has any non-zero counts
int hasdata = 0;
for (int tidx = 0; tidx < TYPTOT; ++tidx) {
if (counts[yidx][tidx]) {
hasdata = 1;
break;
}
}
// skip any years that have no data [optional]
if (! hasdata)
continue;
// output the absolute year
printf("| %d",yidx + YRLO);
// output the counts for each type
for (int tidx = 0; tidx < TYPTOT; ++tidx)
printf(fmt,counts[yidx][tidx]);
printf(" |\n");
}
return 0;
}
Here's the program output for your given input data:
| Year | 100 | 101 | 102 | 103 |
----------------------------------------------------
| 2010 | 7 | 182 | 14 | 0 |
| 2011 | 5 | 176 | 16 | 0 |

How do I concatenate strings to generate fixed width output

I have an array of structures, where each structure contains a first name and a last name, along with other information. I'm trying to print the array in tabular form, something like this
+---------------------------+--------+--------+
| Student Name | Test 1 | Test 2 |
+---------------------------+--------+--------+
| Pousseur, Henri | 95 | 92 |
| Boyer, Charles | 90 | 97 |
+---------------------------+--------+--------+
However, my output looks like this
+---------------------------+--------+--------+
| Student Name | Test 1 | Test 2 |
+---------------------------+--------+--------+
| Pousseur, Henri | 95 | 92 |
| Boyer, Charles | 90 | 97 |
+---------------------------+--------+--------+
My question is, how do I concatenate the last name to the first name (with a comma in between), and then print the whole thing as a fixed width string? So that my table lines up correctly.
Here's my code:
#include <stdio.h>
#define NAME_LEN 25
typedef struct
{
char fname[NAME_LEN+1];
char lname[NAME_LEN+1];
int score1;
int score2;
} STUREC;
void printRecords(STUREC records[], int count)
{
printf("+---------------------------+--------+--------+\n");
printf("| Student Name | Test 1 | Test 2 |\n");
printf("+---------------------------+--------+--------+\n");
for (int i = 0; i < count; i++)
printf ("| %-s, %-26s| %4d | %4d |\n", records[i].lname, records[i].fname, records[i].score1, records[i].score2 );
printf("+---------------------------+--------+--------+\n");
}
int main(void)
{
STUREC records[] = {
{ "Henri" , "Pousseur", 95, 92 },
{ "Charles", "Boyer" , 90, 97 }
};
printRecords(records, 2);
}
Note that printf returns the number of characters printed. So if you want to print the name within a fixed width, you can print the name, and then output spaces as needed to fill the width.
#define WIDTH 26
int count = printf( "%s, %s", records[i].lname, records[i].fname );
if ( count < WIDTH )
printf( "%*s", WIDTH-count, "" );
In the format string "%*s", the * tells printf that the width of the string will be passed as an argument. The WIDTH-count argument is the number of spaces that need to be printed, and "" is just an empty string. So for example, if count is 16, then WIDTH-count is 10, so the printf is equivalent to
printf( "%10s", "" );
which will print 10 spaces.
This is just an adpatation of #user3386109 answer.
Add
#define WIDTH 27 // You get a max width of 26
somewhere in the beginning of your program and a string
char fullname[WIDTH];
somewhere in the beginning of the main.
Then make changes like below :
printf("\n+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
printf("| Student Name | ID | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |\n");
printf("+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
for (i = 0; i < count; i++)
{
int lname_len=strlen(records[i].lname);
int fname_len=strlen(records[i].fname);
snprintf(fullname,WIDTH,"%s,%s%*s", records[i].lname,records[i].fname,(WIDTH>(lname_len+fname_len)?(WIDTH-(lname_len+fname_len)):0),"");
/* The above step concatenates - since you're very interested in it -
* the sirname and the first name into a string fullname making sure
* that the string is padded to 26 characters utmost.
*/
printf ("| %s | %-7.6d| %4d | %4d | %4d | %4d | %4d | %6.2f | %-2s |\n", fullname, records[i].id, records[i].score1,
records[i].score2, records[i].score3, records[i].score4, records[i].score5,
records[i].ave, records[i].grade);
}
printf("+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
printf("\nHave A Terrible Day!\n\n");
Note the ternary expression :
(WIDTH>(lname_len+fname_len)?(WIDTH-(lname_len+fname_len)):0)
in snprintf. This will be evaluated to unused width, if any which we pad with emptry strings "" or null characters.
If you didn't understand it please have a look here

How does odd number print increasing order?

#include <stdio.h>
#include<string.h>
void Magic(int in);
int Even(int n);
int main()
{
Magic(10);
}
void Magic(int in)
{
if(in == 0)
{
return;
}
if(Even(in))
{
printf("%i\n", in);
}
Magic(in - 1);
if(!Even(in))
{
printf("%i\n", in);
}
return;
}
int Even(int n)
{
return (n % 2) == 0 ? 1 : 0;
}
how does odd number print in increasing order?
It prints 10 8 6 4 2 1 3 5 7 9.
I know upto 10 8 6 4 2 but how come it prints 1 3 5 7 9? after decreasing order?
There are nested calls Magic(in - 1);. If number is even it is printed immediately and then Magic(in - 1); is called. Only when n is zero all functions print not even number in reverse order. The first odd number is printed by the deepest Magic() function:
Magic(10)
|print 10
|Magic(9)
| |Magic(8)
| | print 8
| | ...
| | Magic(1)
| | Magic(0)
| | return;
| | print 1
| | return
| | ...
| | return
| |print 9
| |return
|return
this is caused by the recursion of the function. the function is returning in the order it was called. if you want to print the odd numbers in decreasing order after the even numbers, you need to save them in a variable (array ) that is also passed to the magic function

Solving #1015 (Brush) in LightOJ

I am trying to solve the following problem.
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case starts with a blank line. The next line contains an integer N (1 ≤ N ≤ 1000), means that there are N students. The next line will contain N integers separated by spaces which denote the dust unit for all students. The dust unit for any student will not contain more than two digits.
Output
For each case print the case number and the total required dust units.
Sample Input
+--------------+-------------------------+
| Sample Input | Output for Sample Input |
+--------------+-------------------------+
| 2 | Case 1: 16 |
| | Case 2: 100 |
| 3 | |
| 1 5 10 | |
| | |
| 2 | |
| 1 99 | |
+--------------+-------------------------+
Here is my code:
#include <stdio.h>
int main() {
int kase = 0;
int i = 0, j = 0;
do {
scanf("%d", &kase);
} while (kase > 100);
int group[kase];
int tdust[kase];
for (i = 1; i <= kase; i++) {
tdust[i] = 0;
printf("\n");
do {
scanf("%d", &group[i]);
} while (group[i] < 1 || group[i] > 1000);
int stdNumber[group[i]];
for (j = 1; j <= group[i]; j++) {
do {
scanf("%d", &stdNumber[j]);
} while (stdNumber[j] >= 100);
tdust[i] = tdust[i] + stdNumber[j];
}
}
for (i = 1; i <= kase; i++)
printf("\nCase %d: %d", i, tdust[i]);
}
When I submit my code, OnlineJudge says I've got the wrong answer. How can I fix it?
You are getting WA because your code exhibits UB(Undefined Behaviour). You assume that the valid indices for an array of length n where n is a natural number, starts from 1 and ends at n. That is wrong.For an array of length n(n is a natural number), Array indices start from 0 and end at n-1.
To fix it, change
for(i=1; i<=kase; i++)
To
for(i=0; i<kase; i++)
And similarly,do the same for all the other loops. Also change
printf("\nCase %d: %d",i,tdust[i]);
To
printf("\nCase %d: %d",i+1,tdust[i]);
So that you get the desired result.

Resources