How to put an actual variable n in printf("%nd",var) instead of any integer in C? - printf

I'm using %nd in a loop where 'var' increments. Now i want 'n' to be the no. of digits of 'var' so that it aligns correctly

You can specify a variable as the width parameter in printfusing the * width specifier:
printf("%*d\n", digs, var);
This will use the value of the digs variable as the format width.
A simple, complete example:
#include <stdio.h>
int main()
{
for (int i = 1; i <= 10; ++i)
printf("%*d\n", i, i); // i is used both as the width specifier and the actual value printed!
}

I would do it by generating the desired format-string using sprintf() at run-time, like this:
#include <stdio.h>
int main(int, char **)
{
char formatBuf[100];
for (int i=0; i<10; i++)
{
// Note: %% specifies one literal %
// %d specifies the width-number to put in the format string
// ... and the final d is a literal 'd' to include in the format string
sprintf(formatBuf, "num=%%%dd", i);
printf("formatBuf=[%s]\n", formatBuf);
printf(formatBuf, i);
printf("\n");
}
return 0;
}
... which gives this output as a demonstration:
formatBuf=[num=%0d]
num=0
formatBuf=[num=%1d]
num=1
formatBuf=[num=%2d]
num= 2
formatBuf=[num=%3d]
num= 3
formatBuf=[num=%4d]
num= 4
formatBuf=[num=%5d]
num= 5
formatBuf=[num=%6d]
num= 6
formatBuf=[num=%7d]
num= 7
formatBuf=[num=%8d]
num= 8
formatBuf=[num=%9d]
num= 9

Related

uninitialized local variable with cin use

I am working on this code (in c++) and I finished but i have 2 errors on line 19 when I use them in for loops about variables y and m, saying that they are uninitialized local variables. I don't see how this is possible because I declared them at the beginning as int and their value is assigned when the user inputs in cin.
#include <iostream>
#include <string>
#include <cmath>
#include <math.h>
#include <vector>
using namespace std;
int main()
{
int a, b, n, l = 0;
cin >> a, b, n;
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 20; j++)
{
if (l < (i*a + j*b) && (i*a + j*b) <= n)
l = i*a + j*b;
}
}
cout << l;
return 0;
}
I'm not in a position to test this, but Multiple inputs on one line suggests that your syntax should be
cin >> a >> b >> c;
Regardless, I think the compiler is suggesting that assignment to all variables isn't guaranteed by cin so without explicit initialisation when they're declared you're assuming too much.

Blas DGEMV input error

I'm having trouble figuring out why a piece of blas call is throwing n error. The problem call is the last blas call. The code compiles without issue and runs fine up until this call then fails with the following message.
** ACML error: on entry to DGEMV parameter number 6 had an illegal value
As far as I can tell everything the input types are correct and array a has
I would really appreciate an insight into the problem.
Thanks
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cblas.h"
#include "array_alloc.h"
int main( void )
{
double **a, **A;
double *b, *B, *C;
int *ipiv;
int n, nrhs;
int info;
int i, j;
printf( "How big a matrix?\n" );
fscanf( stdin, "%i", &n );
/* Allocate the matrix and set it to random values but
with a big value on the diagonal. This makes sure we don't
accidentally get a singular matrix */
a = alloc_2d_double( n, n );
A= alloc_2d_double( n, n );
for( i = 0; i < n; i++ ){
for( j = 0; j < n; j++ ){
a[ i ][ j ] = ( ( double ) rand() ) / RAND_MAX;
}
a[ i ][ i ] = a[ i ][ i ] + n;
}
memcpy(A[0],a[0],n*n*sizeof(double)+1);
/* Allocate and initalise b */
b = alloc_1d_double( n );
B = alloc_1d_double( n );
C = alloc_1d_double( n );
for( i = 0; i < n; i++ ){
b[ i ] = 1;
}
cblas_dcopy(n,b,1,B,1);
/* the pivot array */
ipiv = alloc_1d_int( n );
/* Note we MUST pass pointers, so have to use a temporary var */
nrhs = 1;
/* Call the Fortran. We need one underscore on our system*/
dgesv_( &n, &nrhs, a[ 0 ], &n, ipiv, b, &n, &info );
/* Tell the world the results */
printf( "info = %i\n", info );
for( i = 0; i < n; i++ ){
printf( "%4i ", i );
printf( "%12.8f", b[ i ] );
printf( "\n" );
}
/* Want to check my lapack result with blas */
cblas_dgemv(CblasRowMajor,CblasTrans,n,n,1.0,A[0],1,B,1,0.0,C,1);
return 0;
}
The leading dimension (LDA) needs to be at least as large as the number of columns (n) for a RowMajor matrix. You’re passing a LDA of 1.
Separately, I’m slightly suspicious of your matrix types; without seeing how alloc_2d_double is implemented there’s no way to be sure if you’re laying out the matrix correctly or not. Generally speaking, intermixing pointer-to-pointer-style “matrices” with BLAS-style matrices (contiguous arrays with row or column stride) is something of a code smell. (However, it is possible to do correctly, and you may well be handling it properly; it’s just not possible to tell if this is the case from the code you posted).

Strlen into a structure

Hello i am trying to use a strlen function in an structure but i am failing badly.
My code is this:
after the scanf i get only the first caracter of the table and in the last print f the programm crashes.
Any suggestions or ideas what i am doing wrong?
Mainly the user will fill the table with alphanumerics and with the strlen i would like to extract the lenght of the alphanumerics.
#include<stdio.h>
#include <string.h>
main(void)
{
int M,N;
struct word_pair /*structure */
{
char word[M]; // the alphanumeric
int lenght; //the lenght of alphanumeric
};
struct word_pair word_table[N]; // the table of alphanumeric and lenght
printf("Enter a frase:");
scanf("%c",&word_table[N].word[M]);
printf("\n Your frase is %c ",word_table[N].word[M]);
printf("\n %u ",(unsigned)strlen(word_table[N].word[M]));
}
You declare an array of word_pair of but you use only one struct in the array and you store it in an invalid position(N). Take into account that when you declare an array of length n such as int a[n]; the valid positions inside the array are from 0 to n - 1.
You must first initialize the variables N and M to whatever value you need. After that, try (assuming that N > 0 and M > 0):
scanf("%c",&word_table[0].word[0]);
printf("\n Your frase is %c ",word_table[0].word[0]);
printf("\n %u ",(unsigned)strlen(word_table[0].word[0]));

Objective c, Scanf() string taking in the same value twice

Hi all I am having a strange issue, when i use scanf to input data it repeats strings and saves them as one i am not sure why.
Please Help
/* Assment Label loop - Loops through the assment labels and inputs the percentage and the name for it. */
i = 0;
j = 0;
while (i < totalGradedItems)
{
scanf("%s%d", assLabel[i], &assPercent[i]);
i++;
}
/* Print Statement */
i = 0;
while (i < totalGradedItems)
{
printf("%s", assLabel[i]);
i++;
}
Input Data
Prog1 20
Quiz 20
Prog2 20
Mdtm 15
Final 25
Output Via Console
Prog1QuizQuizProg2MdtmMdtmFinal
Final diagnosis
You don't show your declarations...but you must be allocating just 5 characters for the strings:
When I adjust the enum MAX_ASSESSMENTLEN from 10 to 5 (see the code below) I get the output:
Prog1Quiz 20
Quiz 20
Prog2Mdtm 20
Mdtm 15
Final 25
You did not allow for the terminal null. And you didn't show us what was causing the bug! And the fact that you omitted newlines from the printout obscured the problem.
What's happening is that 'Prog1' is occupying all 5 bytes of the string you read in, and is writing a null at the 6th byte; then Quiz is being read in, starting at the sixth byte.
When printf() goes to read the string for 'Prog1', it stops at the first null, which is the one after the 'z' of 'Quiz', producing the output shown. Repeat for 'Prog2' and 'Mtdm'. If there was an entry after 'Final', it too would suffer. You are lucky that there are enough zero bytes around to prevent any monstrous overruns.
This is a basic buffer overflow (indeed, since the array is on the stack, it is a basic Stack Overflow); you are trying to squeeze 6 characters (Prog1 plus '\0') into a 5 byte space, and it simply does not work well.
Preliminary diagnosis
First, print newlines after your data.
Second, check that scanf() is not returning errors - it probably isn't, but neither you nor we can tell for sure.
Third, are you sure that the data file contains what you say? Plausibly, it contains a pair of 'Quiz' and a pair of 'Mtdm' lines.
Your variable j is unused, incidentally.
You would probably be better off having the input loop run until you are either out of space in the receiving arrays or you get a read failure. However, the code worked for me when dressed up slightly:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char assLabel[10][10];
int assPercent[10];
int i = 0;
int totalGradedItems = 5;
while (i < totalGradedItems)
{
if (scanf("%9s%d", assLabel[i], &assPercent[i]) != 2)
{
fprintf(stderr, "Error reading\n");
exit(1);
}
i++;
}
/* Print Statement */
i = 0;
while (i < totalGradedItems)
{
printf("%-9s %3d\n", assLabel[i], assPercent[i]);
i++;
}
return 0;
}
For the quoted input data, the output results are:
Prog1 20
Quiz 20
Prog2 20
Mdtm 15
Final 25
I prefer this version, though:
#include <stdio.h>
enum { MAX_GRADES = 10 };
enum { MAX_ASSESSMENTLEN = 10 };
int main(void)
{
char assLabel[MAX_GRADES][MAX_ASSESSMENTLEN];
int assPercent[MAX_GRADES];
int i = 0;
int totalGradedItems;
for (i = 0; i < MAX_GRADES; i++)
{
if (scanf("%9s%d", assLabel[i], &assPercent[i]) != 2)
break;
}
totalGradedItems = i;
for (i = 0; i < totalGradedItems; i++)
printf("%-9s %3d\n", assLabel[i], assPercent[i]);
return 0;
}
Of course, if I'd set up the scanf() format string 'properly' (meaning safely) so as to limit the length of the assessment names to fit into the space allocated, then the loop would stop reading on the second attempt:
...
char format[10];
...
snprintf(format, sizeof(format), "%%%ds%%d", MAX_ASSESSMENTLEN-1);
...
if (scanf(format, assLabel[i], &assPercent[i]) != 2)
With MAX_ASSESSMENTLEN at 5, the snprintf() generates the format string "%4s%d". The code compiled reads:
Prog 1
and stops. The '1' comes from the 5th character of 'Prog1'; the next assessment name is '20', and then the conversion of 'Quiz' into a number fails, causing the input loop to stop (because only one of two expected items was converted).
Despite the nuisance value, if you want to make your scanf() strings adjust to the size of the data variables it is reading into, you have to do something akin to what I did here - format the string using the correct size values.
i guess, you need to put a
scanf("%s%d", assLabel[i], &assPercent[i]);
space between %s and %d here.
And it is not saving as one. You need to put newline or atlease a space after %s on print to see difference.
add:
when i tried
#include <stdio.h>
int main (int argc, const char * argv[])
{
char a[1][2];
for(int i =0;i<3;i++)
scanf("%s",a[i]);
for(int i =0;i<3;i++)
printf("%s",a[i]);
return 0;
}
with inputs
123456
qwerty
sdfgh
output is:
12qwsdfghqwsdfghsdfgh
that proves that, the size of string array need to be bigger then decleared there.

Create a Fraction array

I have to Create a dynamic array capable of holding 2*n Fractions.
If the dynamic array cannot be allocated, prints a message and calls exit(1).
It next fills the array with reduced random Fractions whose numerator
is between 1 and 20, inclusive; and whose initial denominator
is between 2 and 20, inclusive.
I ready did the function that is going to create the fraction and reduced it. this is what I got. When I compiled and run this program it crashes I cant find out why. If I put 1 instead of 10 in the test.c It doesn't crash but it gives me a crazy fraction. If I put 7,8,or 11 in the test.c it will crash. I would appreciate if someone can help me.
FractionSumTester.c
Fraction randomFraction(int minNum, int minDenom, int max)
{
Fraction l;
Fraction m;
Fraction f;
l.numerator = randomInt(minNum, max);
l.denominator = randomInt(minDenom, max);
m = reduceFraction(l);
while (m.denominator <= 1)
{
l.numerator = randomInt(minNum, max);
l.denominator = randomInt(minDenom, max);
m = reduceFraction(l);
}
return m;
}
Fraction *createFractionArray(int n)
{
Fraction *p;
int i;
p = malloc(n * sizeof(Fraction));
if (p == NULL)
{
printf("error");
exit(1);
}
for(i=0; i < 2*n ; i++)
{
p[i] = randomFraction(1,2,20);
printf("%d/%d\n", p[i].numerator, p[i].denominator);
}
return p;
}
this is the what I am using to test this two functions.
test.c
#include "Fraction.h"
#include "FractionSumTester.h"
#include <stdio.h>
int main()
{
createFractionArray(10);
return 0;
}
In your createFractionArray() function, you malloc() space for n items. Then, in the for loop, you write 2*n items into that space... which overruns your buffer and causes the crash.