How do you delete the comma after the number? - c

So I have this exercise from my Coding class and we were tasked to input the user's input. However, we have to remove the comma of the last number of our output, and I'm struggling with how to remove that comma. Can anyone please help?
this is my code
#include <stdio.h>
#define MAX_SIZE 100
int main(){
int arr[MAX_SIZE];
int N, i;
int * ptr = arr;
printf("Enter length: ");
scanf("%d", &N);
for (i = 0; i < N; i++){
printf("Enter element %d: ", i+1);
scanf("%d", ptr);
ptr++;
}
ptr = arr;
printf("[");
for (i = 0; i < N; i++)
{
printf("%d,", *ptr);
ptr++;
}
printf("]");
return 0;
}
for convenience, this is the output I got
Enter length: 5
Enter element 1: 1
Enter element 2: 2
Enter element 3: 3
Enter element 4: 4
Enter element 5: 5
[1,2,3,4,5,]
this is how the output should be
Enter length: 5
Enter element 1: 1
Enter element 2: 2
Enter element 3: 3
Enter element 4: 4
Enter element 5: 5
[1,2,3,4,5]

Simple:
const char *sep = "";
printf( "[" );
for( i = 0; i < N; i++ ) {
printf( "%s%d", sep, arr[ i ] );
sep = ",";
}
printf( "]" );
Put the commas BEFORE the next value to be printed.
Specify the "prefix" to be "", until that is changed to ","
You'd be better off using "array indexing" throughout instead of shifting a pointer around the place... Too easy to forget to reset it to the beginning...
AND, add some code to check that scanf has assigned an integer value to the uninitialised variable 'N'! If the user types "four" in response to the first prompt, the value of N could be anything, even 243,478,658.... That's a LOT of data to be entering... In addition, the code should also check if the user types 120 to fill the 100 elements of the array.
EDIT: In this instance (surrounding brackets), we can even eliminate one line of code.
const char *sep = "[";
for( i = 0; i < N; i++ ) {
printf( "%s%d", sep, arr[ i ] );
sep = ",";
}
printf( "]" );
and then go on to please the "brace-o-phobes" by changing things around
i = 0;
for( char pre = '['; i < N; pre = ',' )
printf( "%c%d", pre, arr[ i++ ] );
putchar( ']' );

You can use a simple ternary to control the format-string in printf, e.g.
for (i = 0; i < N; i++)
{
printf(i ? ",%d" : "%d", *ptr);
ptr++;
}
That only prints a comma before the number for numbers after the first. An equivalent long-form using if-else would be:
for (i = 0; i < N; i++)
{
if (i) {
printf(",%d", *ptr);
}
else {
printf("%d", *ptr);
}
ptr++;
}
Also suggest the final puts ("]"); to ensure your program is POSIX compliant -- outputting a final '\n' before program exit. Likewise, there is no need to call the variadic printf() function to output a single-character. A simple putchar ('['); will do.

Related

I'm trying to design an algorithm which finds the starting letter of each given word and then saves it into an array kinda like a histogram

First of all, I only recently started to learn to code so it might be something pretty obvious that I'm missing. I'm sorry if that's the case.
When given the words, the algorithm always skips the first word and starts from the second one. I tried analyzing it by hand but couldn't figure out the problem. I'd really appreciate it if someone could help me out.
#include <stdio.h>
int main()
{
int n,i;
char word[100][100];
char tmp;
int counter[100];
printf("Enter the number of words ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("Enter the word ");
scanf("%s", word[i]);
}
for(i='a'; i<'z'; i++)
{
counter[i]=0;
}
for(i=0; i<n; i++)
{
tmp=word[i][0];
counter[tmp]=counter[tmp]+1;
}
for(i='a'; i<'z'; i++)
{
printf("%d", counter[i]);
}
return 0;
}
It's hard to tell why the first word is not being counted without seeing the input you are passing to the program, but the 2 issues I see here are:
You are treating the ASCII values of each character as the index. In ASCII, 'A' has a value of 65, 'Z' is 90, 'a' is 97, 'z' is 122. your counter array only goes up to 100, so trying to access counter['z'] will go out of the array bounds and will corrupt memory on the stack and cause unexpected results. Since we are only considering letters and not all ASCII characters, we should make our array sized 26, and we should access it by converting each ASCII char to an index. This can be done by subtracting 'a' (thus 'a'-'a' will yield an index of 0, 'b'-'a' will yield an index of 1, etc.)
You are not considering uppercase letters. These are a different range of ASCII values from lowercase letters, and it is a good idea to convert all letter to lowercase before indexing into our array.
Here is a version of the code with these two changes:
int main()
{
int n,i;
char word[100][100];
char tmp;
const int numLetters = 'z' - 'a' + 1;
int counter[numLetters];
printf("Enter the number of words ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("Enter the word ");
scanf("%s", word[i]);
}
for(i=0; i<numLetters; i++)
{
counter[i]=0;
}
for(i=0; i<n; i++)
{
tmp=word[i][0];
//convert the letter to lowercase
tmp=tolower(tmp);
//subtract tmp-'a' to get the array index
counter[tmp-'a']++;
}
for(i=0; i<numLetters; i++)
{
printf("%d", counter[i]);
}
return 0;
}
You are indexing the array counter[] with character code values 'a'(97) to 'z'(122), but the array length is 100. You are overrunning the buffer, and stomping on adjacent variables - in this case the start of word[0], and probably tmp, but that is uninitialised at that point so has no impact.
What is actually adjacent to a particular variable is undefined and will depend on how the compiler locates and orders data objects in memory; in a different compiler you may well have different results, including simply crashing and aborting.
The initialisation loop is unnecessary; you can zero the entire array thus:
int counter[100] = {0} ;
There are other issues of code safety and style, but semantic errors include your loops stopping one short of 'z'. To include 'z' you need <= 'z' or < 'z'+1:
for( int i = 'a'; i <= 'z'; i++ )
{
printf("%d", counter[i]);
}
Allocating more than 26 elements counter array is unnecessary. Better to calculate the range from the character values:
int counter['z'-'a' + 1] = {0} ;
You should then generate the index by subtracting 'a' from the character code value:
for( int i = 0; i < n; i++ )
{
char index = word[i][0] - 'a' ;
counter[index]++ ;
}
To treat upper and lower case the same you might want to ignore case:
char index = tolower(word[i][0]) - 'a' ;
Your output will make no sense if any letter has a count > 10. You need to delimit each value with space or comma for example.
for( int i = 'a'; i <= 'z'; i++ )
{
printf("%-3d", counter[i]);
}
You can add clarity by defining a constant for the number of characters:
#define NUM_COUNTERS ('z'-'a' + 1)
simplifying the counter[] declaration and the output loop:
int counter[NUM_COUNTERS] = {0} ;
...
for( int i = 0; i < NUM_COUNTERS; i++ )
{
printf( "%-3d ", counter[i - 'a'] ) ;
}
To prevent overrunning words[] you should limit the value if n and further prevent entering more than 99 characters per word.
All together:
#include <stdio.h>
#include <ctype.h>
#define MAX_WORDS 100
#define NUM_COUNTERS ('z'-'a' + 1)
int main()
{
int n = 0 ;
printf( "Enter the number of words " ) ;
scanf( "%d", &n ) ;
if( n > MAX_WORDS )
{
n = MAX_WORDS ;
}
char word[MAX_WORDS][100] ;
for( int i = 0; i < n; i++ )
{
printf( "Enter the word: " );
scanf( "%99s", word[i] ) ;
}
int counter[NUM_COUNTERS] = {0} ;
for( int i = 0; i < n; i++ )
{
char index = word[i][0] - 'a' ;
counter[index]++ ;
}
for( int i = 0; i < NUM_COUNTERS; i++ )
{
printf( "%-3d ", counter[i - 'a'] ) ;
}
return 0;
}

Why fgets() doesn't read after the first element?

I am trying to do this programming project in the book i study:
Write a program that sorts a series of words entered by the user:
Enter word: foo
Enter word: bar
Enter word: baz
Enter word: quux
Enter word:
In sorted order: bar baz foo quux
Assume that each word is no more than 20 characters long. Stop reading when the user enters an empty word (i.e., presses Enter without entering a word). Store each word in a dynamically sllocated string, using an array of pointers to keep track of the strings.
After all words have been read, sort the array (using any sorting technique) and then use a loop to print the words in sorted order.
That is what i am trying:
#include <stdio.h>
#include <string.h>
#define MAX_LENGTH 20
int compare ( const void * p, const void * q);
int main (void){
int n;
printf("How many words do you want to write");
scanf("%d", &n);
fflush(stdin);
char * word[n];
for( int i = 0; i < n; i++){
fprintf(stdout , "Waiting for the word:");
if(fgets(word[i] , MAX_LENGTH +1 , stdin) == "\n")
break;
}
qsort((void *)word,n,sizeof(int),compare);
printf("Ordered list is:\n\n");
for( int i = 0; i < n; i++){
fprintf(stdout , "\t %s", word[i]);
}
}
int compare (const void * p, const void * q){
return strcmp( * (char**) p , * (char **) q);
}
Edit : question with italic is solved thanks to fellow coders here. My new issue is i can't read past the first element of array. And program closes itself.
C:\Users\Lenovo\Desktop\ogrenme\ch17>sorting
How many words do you want to write4
Waiting for the word:asd
C:\Users\Lenovo\Desktop\ogrenme\ch17>
And there is one single annoying error that keeps me prevented from completing the exercise and "chill" with rest of this challenging book:
sorting.c:20:5: warning: implicit declaration of function 'qsort' [-Wimplicit-function-declaration]
qsort((void *)word,n,sizeof(int),compare);
I did a small trial (definitely the code could be optimized)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (void) {
int n = 0;
char **string_list;
char *tmp;
//allocate memory for the first element
string_list = (char**)malloc(sizeof(char*)*1);
//infinite loop
while ( 1 ) {
//allocate size of each element to a max of 20 chars
string_list[n] = (char*)malloc(sizeof(char)*20);
printf("Enter word : ");
fgets (string_list[n], 20, stdin);
//remove trailing return carriage
string_list[n][strlen(string_list[n]) - 1] = '\0';
//break the loop here if user enters empty string
if (strlen(string_list[n]) < 1) {
break;
}
//add counter
n++;
//add memory to contain another element
string_list = realloc(string_list, sizeof(char*)*(n+1));
}
printf("\n\nInitial List is:\n");
for (int i=0 ; i<n-1 ; i++) {
printf("%s - ", string_list[i]);
}
printf("%s\n\n", string_list[n-1]);
//sorting the list
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
if (strcmp(string_list[i], string_list[j]) < 0) {
tmp = string_list[i];
string_list[i] = string_list[j];
string_list[j] = tmp;
}
}
}
printf("Sorted List is:\n");
for (int i=0 ; i<n-1 ; i++) {
printf("%s - ", string_list[i], strlen(string_list[i]));
}
printf("%s\n\n", string_list[n-1], strlen(string_list[n-1]));
}
output
$ ./sort
Enter word : foo
Enter word : bar
Enter word : baz
Enter word : quux
Enter word :
Initial List is:
foo - bar - baz - quux
Sorted List is:
bar - baz - foo - quux

Why isn't this C code's \t working?

I am trying to print a pattern of numbers. Try running this code with a input of 20, you will see that the tab spaces are all in the wrong place, they don't follow the order. I know that the tab spaces jump to the next header, but is there a way to avoid it?
#include <stdio.h>
int main()
{
int i, n, count = 0;
scanf("%d", &n);
for(i = 1; i <= n; i++)
{
printf("%dnumber\t", i);
count++;
if(count == 4)
{
count = 0;
printf("\n");
}
}
return 0;
}
Note: Is there a way to do this with tab spaces only(i.e., "\t" only) instead of using an ordinary white space.
Here is the output that I am getting.
But what I want is this
There are several different problems here.
But it sounds like your main question is "gee: the tabs don't line up like I expect."
SUGGESTED ALTERNATIVE:
Consider using "field length specifiers" in printf():
http://www.cplusplus.com/reference/cstdio/printf/
EXAMPLE:
printf ("%-20s", mystring); // Will always be exactly 20 characters
printf ("%06d", myint); // 6-digits, zero filled
Why not:
#include <stdio.h>
int main( void )
{
int i = 0;
int n = 0;
scanf( "%d", &n );
for( i = 1; i <= n; i++ )
{
printf( "%02dnumber\t", i );
if( i % 4 == 0 )
printf("\n");
}
return 0;
}
Output:
16
01number 02number 03number 04number
05number 06number 07number 08number
09number 10number 11number 12number
13number 14number 15number 16number
Hope it helps!

Return Value Function in C

Hello I'm working on a quick program that generates a master code and the user has to guess the code. When checking the user's guess I use 2 functions one for Exact Matches and the other for close matches (where they got a number that's in the mastercode but not in the right location)
Ex. master code 1 2 3 4
user 2 3 2 4
the output the should show the user has 2 close matches and one exact match. I'm having trouble understanding how to properly return an int.
My ouput just shows the default value of exactMatch and closeMatch when I try to print them in Main. any insight will be greatly appreciated. Thank you.
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#define CODELENGTH 4
#define NUMSYMBOLS 6
int MasterCode[4];
int guess[ 4 ];
int exactMatch;
int closeMatch=0;
void genCode (int MasterCode[])
{
int i=0;
int k;
while (i < CODELENGTH){
MasterCode[i] =rand() %NUMSYMBOLS +1;
i++;
}//end while loop.
for ( k = 0 ; k < 4; k++ ) {
printf( "%d ", MasterCode[ k ] );
}
printf( "\n" );
}
void getGuess (int guess[])
{
int number = 0;
printf( "Please enter your list of 4 numbers between 1 and 6: " );
int j;
int k;
for ( j = 0 ; j < 4; j++ ) {
scanf( "%d", &number );
guess[ j ] = number;
}
printf( "Your array has these values: " );
for ( k = 0 ; k < 4; k++ ) {
printf( "%d ", guess[ k ] );
}
printf( "\n" );
}
int main (int argc, char **argv)
{
srand ( time(NULL) );
genCode(MasterCode);
getGuess(guess);
checkExactMatches(MasterCode, guess, exactMatch);
checkCloseMatches(MasterCode, guess, closeMatch);
printf("%d = Ending exactMatches \n", exactMatch);
printf("%d = Ending closeMatches \n", closeMatch);
}
int checkExactMatches (int MasterCode[], int guess[], int exactMatch )
{
int woot;
for(woot=0; woot<4; woot++){
if (MasterCode[woot] == guess[woot]){
printf("Exact Match found \n");
exactMatch ++;
printf( "%d = Guess \n" , guess[ woot ]);
printf( "%d = MasterCode \n", MasterCode[ woot ]);
printf("%d = exactMatch \n", exactMatch);
}// end if
if (MasterCode[woot] != guess[woot])
printf("No EXACT match \n");
}//end for loop
return exactMatch;
} // end checkExactMatches
int checkCloseMatches (int MasterCode[], int guess[], int closeMatch )
{
int k;
int j;
for(k=0; k<4; k++){
for (j=0; j<4; j++) {
if (MasterCode[k] == guess[j]){
printf("CLOSE Match found \n");
closeMatch ++;
printf( "%d = Guess \n" , guess[ j ]);
printf( "%d = MasterCode \n \n", MasterCode[ k ]);
printf("%d = closeMatch \n \n", closeMatch);
}// end if
if (MasterCode[k] != guess[j])
printf("No CLOSE match \n");
}//end nested for loop
}//end for loop
return closeMatch;
} // end checkCloseMatches
Getting the value returned from a function is actually really easy, it's basically the same as assigning a value to a variable. In your case, the syntax would be something like this:
int result = checkExactMatches(MasterCode, guess, exactMatch);
result will now hold the value returned by the function.
What you need to do is
Not pass the count arguments to the function and
Instead collect the return value of the function in the count
So
checkExactMatches(MasterCode, guess, exactMatch);
becomes
exactMatch = checkExactMatches(MasterCode, guess);
You need to make appropriate changes to the function header and also avoid using global variables.
Note that while arrays are passed by pointer (meaning that the function can modify the pointed-to pointer), ints are passed by value. Therefore, changes to the int within a function only persist for the duration of the function.
You want to use
exactMatch = checkExactMatches(MasterCode, guess);
and in that case you won't have to pass in exactMatch any more.
C passes arguments by value, rather than by reference, so passing int exactmatch into the function creates a duplicate of the data inside exactmatch, so operations done inside the method don't do anything.
What you want to do is remove exactmatch from the argument list, and instead assign it as zero (int exactmatch=0; at the beginning of the method, remove exactmatch from the global variables, and use something like int resultExact = checkExactMatches(MasterCode, guess); as your function call. You're already returning the answer correctly, you just don't pick up that answer anywhere.

Using command line in C to detect arguments, and then print out the first or second char of the arguments

I need to make a program that accepts no less than 2 and no more than 6 arguments at the command line and then prints out the 1st or 2nd character
EX: asdf asdf asdf asdf
prints out as: a s a s
I have the initial array setup and working, the for loops below are meant to cut the string off at a space in the input and copy it to a new string, but it is not working correctly. I am new to C, and to this site. Any help is greatly appreciated.
#include <stdio.h>
#include <string.h>
int main(){
char a[50];
char b[50];
char c[50];
char d[50];
char e[50];
char f[50];
int i;
printf("enter a string (Ex: asdf asdf asdf... Must have atleast 2 arguments but no more than six): ");
scanf("%s", a);
printf("%c", a);
for (i = 0; i != 50; i++){
if(a[i]==' '){
char strncpy(b, &a[i], i+2);
printf("\n%c ",a[1]);
printf("%c ",b[0]);
}
}
for (i = 0; i != 50; i++){
if(b[i]==' '){
char strncpy(c, &b[i], i+2);
printf("%c ",c[1]);
}
}
for (i = 0; i != 50; i++){
if(c[i]==' '){
char strncpy(d, &c[i], i+2);
printf("%c ",d[0]);
}
}
for (i = 0; i != 50; i++){
if(d[i]==' '){
char strncpy(e, &d[i], i+2);
printf("%c ",e[1]);
}
}
for (i = 0; i != 50; i++){
if(e[i]==' '){
char strncpy(f, &e[i], i+2);
printf("%c ",f[0]);
}
}
return 0;
}
You don't need to copy your strings out of anywhere... Coming from the command line you'll have them sitting in argv:
int main( int argc, char **argv )
{
}
Where argc is the total number of arguments plus 1 (the first is the name that invoked your program), and argv is an array of pointers to each argument string. These have already been tokenised from the command-line.
So first you wanna test you have enough arguments. I like to explicitly make a new variable to remove the off-by-one confusion from comparisons:
int nparams = argc - 1;
if( nparams < 2 || nparams > 6 ) {
printf( "Wrong number of arguments\n" );
return -1;
}
Then you loop over your arguments. The first will be in position 1 of the array... From your example, it seems that you print the first character of the first argument, and the second character of the next, then continue alternating. That's a modulo operation. I have a variable which that chooses which character to print.
int i, which;
for( i = 1; i <= nparams; i++ ) {
which = (i-1) % 2;
printf( "%c\n", argv[i][which] );
}
This does assume that every second argument is at least two characters long. No error checking. If you need error checking, you need to make sure that the character you're printing is not the string-terminator (value 0). In the case of the second character, you also need to check the value before it is not 0. I don't know if it's possible to specify an argument that is a string of zero length. Perhaps a reader who does know can comment.
Well, I may as well put it in... So your loop would look a little like this:
if( argv[i][0] == 0 || argv[i][which] == 0 ) {
printf( "\n" );
} else {
printf( "%c\n", argv[i][which] );
}

Resources