What am I doing right? I am trying to learn a function.
This should be like this output:
*
***
*****
*******
My code:
#include <stdio.h>
#include <stdlib.h>
void pyramid (int n)
{
int width = 0;
if ( n )
{
++width;
pyramid( f, n - 1 );
for ( unsigned int i = 0; i < 2 * n - 1; i++ )
{
fprintf( f, "%*c", i == 0 ? width : 1, '*' );
}
fputc( '\n', f );
--width;
}
}
int main (int argc, char *argv[])
{
if (argc < 2)
{
printf ("usage: h4 <number>\n");
return 1;
}
pyramid (atoi (argv[1]));
return 0;
}
OUTPUT:
Python 3.6.1 (default, Dec 2015, 13:05:11)
[GCC 4.8.2] on linux
Traceback (most recent call last):
File "python", line 4
void pyramid (int n) {
^
SyntaxError: invalid syntax
Why is this problem? Please help me and explain. Thank you. I'm deaf C programmer beginner.
Another way to approach outputting the pyramid (centered) would be to use the field width modifier for your printf format string for the padding rather than the fill character itself. Then you can simply loop outputting the number of characters needed per line (which increases by 2 each line, e.g. 1, 3, 5, ...).
For example, taking the number of lines of output as the first argument to your program, (or using 4 by default if no argument is given), you could do something similar to the following:
#include <stdio.h>
#include <stdlib.h>
#define FILL '*'
void pyramid (int n)
{
if (n < 1) /* validate positive value */
return;
int l = 1, /* initial length of fill chars */
max = n * 2 - 1, /* max number of fill chars */
pad = max / 2; /* initial padding to center */
for (int i = 0; i < n; i++) { /* loop for each line */
if (pad) /* if pad remains */
printf ("%*s", pad--, " "); /* output pad spaces */
for (int j = 0; j < l; j++) /* output fill chars */
putchar (FILL);
putchar ('\n'); /* output newline */
l += 2; /* increment fill by 2 */
}
}
int main (int argc, char **argv) {
int n = argc > 1 ? (int)strtol (argv[1], NULL, 0) : 4;
pyramid (n);
return 0;
}
(note: you can use unsigned types throughout to insure positive values, or you can simply validate you have positive values. You should also include errno.h and validate the strtol conversion, though it will return 0 if no digits are provided)
It also helps to #define your fill character at the top of the code, so you have a convenient place for change should you want another character. It prevents digging through your function to find the constant later on.
Example Use/Output
$ ./bin/pyramidtop 1
*
$ ./bin/pyramidtop 5
*
***
*****
*******
*********
$ ./bin/pyramidtop 10
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
Disregarding for a minute how you seem to be running it with python, you are recursively calling the funtion here:
pyramid( f, n - 1 );
However, you only have it defined with one parameter, not with two.
Also, f is undefined.
Your file is a C file, try to compile it with gcc, not executing it with python
And you have some f variable that is not declared used, you can correct this:
#include <stdio.h>
#include <stdlib.h>
void pyramid (FILE *f, int n) {
int width = 0;
if ( n )
{
++width;
pyramid(f, n - 1 );
for ( unsigned int i = 0; i < 2 * n - 1; i++ )
{
fprintf( f, "%*c", i == 0 ? width : 1, '*' );
}
fputc( '\n', f );
--width;
}
}
int main (int argc, char *argv[])
{
if (argc < 2)
{
printf ("usage: h4 <number>\n");
return 1;
}
pyramid (stdout, atoi (argv[1]));
return 0;
}
Will give
*
***
*****
Your code can be updated to add spaces before stars and simplified:
Use clear variable names (stars instead of n)
2. Do not use fprintf where a simple fputc is enough
One variable is used to count stars, use one other to count spaces.
Will this consideration, your code should look like:
#include <stdio.h>
#include <stdlib.h>
/* use clear variable names */
void pyramid (FILE *f, int stars, int spaces) {
if ( stars>0 )
{
pyramid(f, stars -2, spaces + 1 );
for ( unsigned int i = 0; i < spaces; i++ )
{
/* use fputc when enough */
fputc(' ', f );
}
for ( unsigned int i = 0; i < stars; i++ )
{
fputc('*', f );
}
fputc( '\n', f );
}
}
int main (int argc, char *argv[])
{
if (argc < 2)
{
printf ("usage: h4 <number>\n");
return 1;
}
pyramid (stdout, atoi (argv[1]), 0);
return 0;
}
It gives:
*
***
*****
I wrote a much shorter, simpler version, using the formatting features of printf
#include <stdio.h>
int main(void) {
int height = 15;
char s[2*height-1];
memset(s,'*',2*height-1);
for(int i = 0; i<height; ++i)
{
printf("%*.*s\n", height+i,2*i+1,s);
}
return 0;
}
Output
Success #stdin #stdout 0s 9424KB
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
*********************
***********************
*************************
***************************
*****************************
Related
I am working on a string search and replace project. I can only change 1 of the target pattern in the sentence. But I can find both.
Example: just do it. you will do it.
find: do
replace: think
expected---> just think it. you will think it.
what actually happened ---> just do it. you will think it.
How can I replace both of them?
I read the sentence from file input.txt
# include <limits.h>
# include <string.h>
# include <stdio.h>
#include <sys/time.h>
# define NO_OF_CHARS 256
# define MAX 10000
int sum = 0;
int control = 0;
// A utility function to get maximum of two integers
int max (int a, int b) { return (a > b)? a: b; }
// The preprocessing function for Boyer Moore's bad character heuristic
void badCharHeuristic( char *str, int size, int badchar[NO_OF_CHARS]) {
int i;
// Initialize all occurrences as -1
for (i = 0; i < NO_OF_CHARS; i++)
badchar[i] = -1;
// Fill the actual value of last occurrence of a character
for (i = 0; i < size; i++)
badchar[(int) str[i]] = i;
}
/* A pattern searching function that uses Bad Character Heuristic of Boyer Moore Algorithm */
void search( char *txt, char *pat,char temp3[MAX],int k,char*r) {
int m = strlen(pat);
int n = strlen(txt);
char src[MAX],p[MAX],temp[MAX],temp2[MAX],tempP[MAX],out[MAX];
int badchar[NO_OF_CHARS],i,leng,l,count;
char v;
/* Fill the bad character array by calling the preprocessing function badCharHeuristic() for given pattern */
badCharHeuristic(pat, m, badchar);
leng = strlen(pat);
strcpy(tempP,r);
//strcat(tempP,"</mark>");
leng = strlen(pat);
l = strlen(txt);
int s = 0; // s is shift of the pattern with respect to text
while(s <= (n - m)) {
int j = m-1;
/* Keep reducing index j of pattern while characters of pattern and text are matching at this shift s */
while(j >= 0 && pat[j] == txt[s+j]) {
count++;
j--;
}
/* If the pattern is present at current shift, then index j will become -1 after the above loop */
if (j < 0) {
//printf("pattern occurs at shift = %d\n", s);
/* Shift the pattern so that the next character in text
aligns with the last occurrence of it in pattern.
The condition s+m < n is necessary for the case when
pattern occurs at the end of text */
printf("The desired pattern was found starting from %d. line at position %d\n",k,s+1);
strncpy(temp, txt, s);
temp[s] = '\0';
//strcat(temp,"<mark>");
control++;
strcat(temp,tempP);
for(i=0;i<MAX;i++) {
if((s+leng+i)<strlen(txt))
temp2[i] = txt[s+leng+i];
else
temp2[i] = v;
}
strcat(temp,temp2);
strcpy(temp3,temp);
s += (s+m < n)? m-badchar[txt[s+m]] : 1;
}
else
/* Shift the pattern so that the bad character in text
aligns with the last occurrence of it in pattern. The
max function is used to make sure that we get a positive
shift. We may get a negative shift if the last occurrence
of bad character in pattern is on the right side of the
current character. */
s += max(1, j - badchar[txt[s+j]]);
}
sum +=count;
}
/* Driver program to test above funtion */
int main() {
char txt[MAX],p[MAX],r[MAX],temp[MAX],temp2[MAX],tempP[MAX],out[MAX];
int k = 1;
FILE *input = fopen("input.txt","r");
FILE *output = fopen("output.txt","w");
printf("Enter the text in which pattern is to be searched:");
fgets(p, MAX, stdin);
printf("Enter the text in which pattern is to be replaced:");
fgets(r, MAX, stdin);
struct timeval tv1, tv2;
gettimeofday(&tv1, NULL);
p[strlen(p)-1]='\0';
temp[1]='a';
while(!feof(input)){
if(fgets (txt, MAX, input)!=NULL) {
txt[strlen(txt)-1] = '\0';
search(txt, p,temp,k,r);
if(temp[1]!='a') {
fprintf(output,"%s\n",temp);
temp[1]='a';
}
else
fprintf(output,"%s\n",txt);
}
k++;
}
if(control==0) {
printf("\nThe pattern was not found in the given text\n\n");
}
gettimeofday(&tv2, NULL);
printf ("Total time = %f seconds\n", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec));
fclose(input);
fclose(output);
printf("The number of character comparison: %d\n",sum);
return 0;
}
I am tasked with reading a matrix from a text file and find out if it is a magic square, I also have to make sure that all the entries of the matrix are integers and if not I have to write to the standard output an ERROR message while also describing the position where this error occurred.
Now, I succeeded in reading all the elements of matrix but I have a problem with the verification if it is an integer or not.
I used fscanf() because I know that on success it returns the number of elements it succeeded reading correctly and returns EOF or 0 otherwise.
Here is the matrix:
3
12 3 87
78 a 9
45 0 23
first element is the number of rows and columns.
and here is my code ( the part I need help with at least )
while(!feof(file))
{
while ( fgets(buffer, sizeof(buffer), file) )
{
for ( int j = 0; j < n; j++ )
{
if ( i == n )
{
break;
}
m = fscanf(file, "%d", &a[i][j]);
printf("\n%d", m);
if ( m == 0 || m == EOF )
{
printf("\nERROR, %d, %d, %d \n", i, j, a[i][j]);
}
}
i++;
}
}
and here is my output ( right now I'm just trying to figure out this problem so this is not how it will look later on ):
1
1
1
1
0
ERROR, 1, 1, 0
0
ERROR, 1, 2, 48
1
1
1
12 3 87
78 0 48
45 0 23
When I replace 'a' with a number of type (float) for example it will display the ERROR message just for a[1][1] BUT it will replace 9 with 48.
When I have a character ( like in this case ) it will display an ERROR message both for a[1][1] ('a') and a[1][2] ('9') and replace it too.
And my question is why does this happen and what the hell happens between a[1][1] and a[1][2] and how to fix it.
EDIT:I know I could simply exit the program when I find 1 case but I'm really curious on why does this error happen.
fscanf(file, "%d", &n );//I read the first integer, which is also the maximum capacity of my 2d array
int a[n][n];
First points:
while(!feof(file))
{
You will want to look at Why is while ( !feof (file) ) always wrong?. Further, the entire outer loop is superfluous to your code and can simply be removed.
With any of the scanf family of functions, when input does not match the conversion specifier used in the format string, a matching failure occurs, character extraction from the input stream stops at the point of failure, the offending characters causing the failure are left in the input stream (unread) just waiting to bite you on your next attempted read. Attempting to read 'a' as type int with scanf produces a matching failure.
How To Handle A Matching Failure?
Since you always validate all user input, as you note, you detect an input failure with scanf when the return is less than the number of conversions specified (or EOF). Reading an integer at a time with fscanf within your loops tells you exactly where the input failure happened from a row/col standpoint when reading a square matrix worth of data. Knowing where the failure occurred you can output the row/col where the invalid data was encountered.
To capture the invalid data for reporting purposes, you can simply scan forward with fgetc reading a character at a time and filling a buffer with the offending characters until the next valid digit or +/- (explicit sign for a digit) is encountered (you can use ungetc at that point to put the valid digit (or sign) back in the input stream if your wanted to continue reading additional values)
A Short Example
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXC 1024
int main (int argc, char **argv) {
int **m = NULL;
unsigned dim = 0;
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
if (fscanf (fp, "%u", &dim) != 1) { /* read square mtrx dim */
fputs ("error: invalid format, no dimension.\n", stderr);
return 1;
}
if (!(m = malloc (dim * sizeof *m))) { /* allocate/validate dim ptrs */
perror ("malloc-m");
return 1;
}
for (unsigned i = 0; i < dim; i++) /* allocate dim rows of dim int */
if (!(m[i] = calloc (dim, sizeof *m[i]))) { /* zero mem w/calloc */
perror ("calloc-m[i]");
return 1;
}
for (unsigned i = 0; i < dim; i++) /* for each row */
for (unsigned j = 0; j < dim; j++) { /* for each col */
if (fscanf (fp, "%d", &m[i][j]) != 1) { /* read/validate int */
char buf[MAXC], *p = buf; /* buf and ptr to buf */
int c; /* int for char */
/* read while !EOF, not digit and not -/+ */
while ((c = fgetc(fp)) != EOF && (c < '0' || '9' < c) &&
c != '-' && c != '+')
if (!isspace(c)) /* if not a space */
*p++ = c; /* store offending char(s) */
*p = 0; /* nul-terminate buf */
if (c != EOF) /* if c a char - put it back */
ungetc(c, fp);
/* output location of invalid input */
printf ("error: m[%d][%d] - invalid entry '%s'.\n",
i, j, buf);
return 1; /* and bail - or continue -- your choice */
}
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
for (unsigned i = 0; i < dim; i++) { /* for each row */
for (unsigned j = 0; j < dim; j++) /* for each col */
printf (" %3d", m[i][j]); /* output value */
putchar ('\n'); /* output newline */
free (m[i]); /* free ints in row */
}
free (m); /* free pointers */
return 0;
}
(note: you didn't say how you allocated storage, so a simple pointer to pointer to int was used to allocate dim pointers and a block of dim integers was allocated and the starting address for each allocation assigned to each of the pointer to allow indexing as a 2D array)
Example Input Files
Using your example input with invalid int at [1][1]:
$ cat ~/tmpd/mtrx.txt
3
12 3 87
78 a 9
45 0 23
An example with good values:
$ cat ~/tmpd/mtrxgood.txt
3
12 3 87
78 8 9
45 0 23
Example Use/Output
With invalid int at [1][1]:
The program correctly reports the location and the offending character:
$ ./bin/readsquaremtrx ~/tmpd/mtrx.txt
error: m[1][1] - invalid entry 'a'.
With good values, all values are read and the matrix printed to the screen before all allocated memory is freed:
$ ./bin/readsquaremtrx ~/tmpd/mtrxgood.txt
12 3 87
78 8 9
45 0 23
The code is commented to help you follow along. If you have any questions, just let me know.
Key Issue of your Code: Your FILE pointer doesn't move ahead when fscanf encounters an error. You need to move it ahead using fseek.
Some of the issues you need to look at:
How to allocate an array of sufficient size to read all inputs correctly
File based error handling and how to move the FILE pointer ahead if it hits an error while reading using fscanf. My below code considers
only the specific case of a single incorrect character being present,
you will have to handle it appropriately if more than one character is
present.
There is no need for you to do both fgets and fscanf. Only one is sufficient.
Relook, if you really want to use fscanf. The same logic can be achieved using other read methods related to FILE.
Treat the below code strictly as a pseudo code, just giving some indications. This doesn't handle all conditions at all. You need to work on lot of aspects of your code and handle additional error conditions etc. I have just given a pointer on how you can solve it.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *f = fopen("./check.txt", "r");
int a[3][3] = {0};
int n, res, i;
res = fscanf(f, "%d", &n);
i = 0;
while(i<n)
{
for(int j = 0; j < n; j++)
{
int val = 0;
res = fscanf(f, "%d", &val);
if ((res == 0) || (res == EOF))
{
printf("Error: res = %d for i = %d, j = %d, val = %d\n", res, i, j, val);
fseek(f, 1, SEEK_CUR);
}
else
a[i][j] = val;
}
i++;
}
printf("The Matrix\n");
for(int i = 0; i<n; i++)
{
for (int j=0; j<n; j++)
printf("%d ", a[i][j]);
printf("\n");
}
}
Output:
Error: res = 0 for i = 1, j = 1, val = 0
The Matrix
12 3 87
78 0 9
45 0 23
Another example using a flat memory region instead of a somwhat inefficient "array" of pointers to pointers:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
int is_magic_square(int *square, size_t dimension)
{
if(dimension < 3) {
return 0;
}
int prev_row_sum;
int prev_col_sum;
int d1_sum = 0;
int d2_sum = 0;
for (size_t y = 0; y < dimension; ++y) {
int curr_row_sum = 0;
int curr_col_sum = 0;
for (size_t x = 0; x < dimension; ++x) {
curr_row_sum += square[y * dimension + x];
curr_col_sum += square[x * dimension + y];
if (x == y) {
d1_sum += square[y * dimension + x];
d2_sum += square[y * dimension + dimension - 1 - x];
}
}
if (y && (curr_row_sum != prev_row_sum || curr_col_sum != prev_col_sum)) {
return 0;
}
prev_row_sum = curr_row_sum;
prev_col_sum = curr_col_sum;
}
return prev_row_sum == d1_sum && prev_row_sum == d2_sum ? prev_row_sum : 0;
}
int main(void)
{
char const *filename = "test.txt";
FILE *input = fopen(filename, "r");
if (!input) {
fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
return EXIT_FAILURE;
}
size_t dimension;
if (fscanf(input, " %zu", &dimension) != 1) {
fprintf(stderr, "Faild to read squares dimensions from \"%s\" :(\n\n", filename);
fclose(input);
return EXIT_FAILURE;
}
int result = EXIT_FAILURE;
printf("Reading a %zu x %zu square from \"%s\" ...\n\n", dimension, dimension, filename);
int *square = calloc(dimension * dimension, sizeof(*square));
if (!square) {
fputs("Not enough memory :(\n\n", stderr);
goto cleanup;
}
for (size_t y = 0; y < dimension; ++y, putchar('\n')) {
for (size_t x = 0; x < dimension; ++x) {
int value;
if (fscanf(input, " %d", &value) != 1 || value < 1) {
fprintf(stderr, "\n\nFailed to read value at (%zu, %zu) from \"%s\" :(\n\n",
x + 1, y + 1, filename);
goto cleanup;
}
for (size_t pos = 0; pos < y * dimension + x; ++pos) {
if (square[pos] == value) {
fprintf(stderr, "\n\nDuplicate value %d found at (%zu, %zu) in \"%s\" :(\n\n",
value, x + 1, y + 1, filename);
goto cleanup;
}
}
if(value > dimension * dimension) {
fprintf(stderr, "\n\nValue %d at (%zu, %zu) in \"%s\" is out of range 1, 2, ..., %zu^2 :(\n",
value, x + 1, y + 1, filename, dimension);
goto cleanup;
}
printf("%4d ", value);
square[y * dimension + x] = value;
}
}
int sum = is_magic_square(square, dimension);
printf("\nThis %s a perfect square!\n", sum ? "is" : "is not");
if (sum) {
printf("It's sum is %d.\n", sum);
}
putchar('\n');
result = EXIT_SUCCESS;
cleanup:
free(square);
fclose(input);
return result;
}
Sample Input:
4
10 3 13 8
5 16 2 11
4 9 7 14
15 6 12 1
Sample Output:
Reading a 4 x 4 square from "test.txt" ...
10 3 13 8
5 16 2 11
4 9 7 14
15 6 12 1
This is a perfect square!
It's sum is 34.
I want to be able to input a string (with spaces) and have it displayed like a moving sign. For example:
Input:
Hello World!
5 (This signifies the number of characters the sign can hold)
Output:
Sign #1:
[Hello]
[ello ]
[llo W]
[lo Wo]
[o Wor]
[ Worl]
[World]
[orld!]
[rld! ]
[ld! H]
[d! He]
[! Hel]
This is what I have so far. If someone could direct me on what to do next I would greatly appreciate it!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int num_of_chars, i;
char sign[30];
char *arrayofsign = malloc(10 * sizeof(char));
scanf("%[^\n]s", sign);
arrayofsign = sign;
printf("%s\n", arrayofsign);
scanf("%d", &num_of_chars);
for (i = 0; i < num_of_chars; i++) {
printf("[]");
}
}
Use carriage return '\r' to move the cursor back to the beginning of a line. Assuming a POSIX system (because of the use of nanosleep()), you could code like this. Note the use of the %*.*s notation to specify how long a sub-section of the string to print.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(void)
{
char sign[50];
struct timespec d = { .tv_sec = 0, .tv_nsec = 100000000 };
printf("What should I say? ");
if (scanf("%49[^\n]", sign) == 1)
{
printf("Sign: [%s]\n\n", sign);
int t_len = strlen(sign);
for (int i = 0; i < 10; i++)
{
for (int l_len = 0; l_len < t_len; l_len++)
{
int r_len = t_len - l_len;
/* Rotate to right */
//printf("\r[%*.*s%*.*s]", l_len, l_len, sign + r_len, r_len, r_len, sign);
/* Rotate to left */
printf("\r[%*.*s%*.*s]", r_len, r_len, sign + l_len, l_len, l_len, sign);
fflush(stdout);
nanosleep(&d, 0);
}
}
putchar('\n');
}
return 0;
}
The output at the end was:
What should I say? Hello World, and how are you today?
Sign: [Hello World, and how are you today?]
[?Hello World, and how are you today]
It would be better if the code added a string such as " ... " after the entered text so it wraps better. That is trivial to do if you reserve enough space in the string for the padding on input (change 49 into 44 since there are five characters in the padding).
Piping the output through tr '\r' '\n' yields:
Hello World, and how are you today?
What should I say? Sign: [Hello World, and how are you today?]
[Hello World, and how are you today?]
[ello World, and how are you today?H]
[llo World, and how are you today?He]
[lo World, and how are you today?Hel]
[o World, and how are you today?Hell]
[ World, and how are you today?Hello]
[World, and how are you today?Hello ]
[orld, and how are you today?Hello W]
[rld, and how are you today?Hello Wo]
[ld, and how are you today?Hello Wor]
[d, and how are you today?Hello Worl]
[, and how are you today?Hello World]
[ and how are you today?Hello World,]
[and how are you today?Hello World, ]
[nd how are you today?Hello World, a]
[d how are you today?Hello World, an]
[ how are you today?Hello World, and]
[how are you today?Hello World, and ]
…
which shows how the output changes over time. It also illustrates the problems with piping standard output to another command.
An alternative (simpler) version of the printf() statements:
/* Rotate to right */
putchar('\r');
printf("[%.*s%.*s]", l_len, sign + r_len, r_len, sign);
printf(" ");
/* Rotate to left */
printf("[%.*s%.*s]", r_len, sign + l_len, l_len, sign);
That code shows the text scrolling both to the right and to the left at once. In this context, the leading * in the %*.*s conversion specification isn't needed (but there are others where it can be useful and even necessary), so only one length argument is needed for each string.
It's not exactly clear from the question what problem are you having, but I hope that a working source code example will help you anyway.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
//There is no built-in "sleep" in C99, hence this function. You can use any method you want to implement a delay.
void customSleep( int seconds )
{ // Pretty cross-platform, both ALL POSIX compliant systems AND Windows
#ifdef _WIN32
Sleep( 1000 * seconds );
#else
sleep( seconds );
#endif
}
int main(){
char text[30];
int signLength;
printf("Enter text: ");
scanf ("%[^\n]%*c", text); //Reading a line with spaces.
printf("Enter sign length: ");
scanf("%d", &signLength);
printf("SignLength: %d\n", signLength);
printf("Text: %s\n", text);
int currentStartPosition = 0;
setbuf(stdout, NULL); //disable buffering for stdout. Otherwise, if the string is short, it doesn't print immediately.
//Alternatively, you could print a new line character at the end.
while (1) {
for (int i = 0; i < signLength; ++i) {
int indexOfCharacterToPrint = (currentStartPosition + i) % strlen(text);
printf("%c", text[indexOfCharacterToPrint]);
}
++currentStartPosition;
customSleep(1);
//Stole this method from other answers :)
printf("\r");
}
}
Additional links:
Implement time delay in C (SO question).
Why does printf not flush after the call unless a newline is in the format string? (SO question)
Do you mean the following?
#include <stdio.h>
#include <string.h>
int main( void )
{
char s[] = "Hello World!";
size_t n = strlen( s );
size_t m = 5;
for ( size_t i = 0; i < n; i++ )
{
putchar( '[' );
for ( size_t j = 0; j < m; j++ )
{
char c = s[(i + j) % ( n + 1 )];
if ( !c ) c = ' ';
putchar( c );
}
printf( "]\n" );
}
}
The program output is
[Hello]
[ello ]
[llo W]
[lo Wo]
[o Wor]
[ Worl]
[World]
[orld!]
[rld! ]
[ld! H]
[d! He]
[! Hel]
If so then all you need to do is to add inputting of the string and the value of the variable m.
You should repeatedly output the signage display, go back to the beginning of the line with \r, wait a bit and start again with starting point one position to the right in the signage string:
#include <stdio.h>
#include <unistd.h>
int main(void) {
int num_of_chars;
size_t i;
char sign[30];
char arrayofsign[60];
if (scanf("%29[^\n]", sign) != 1 || *sign == '\0') {
printf("invalid input\n");
exit(1);
}
strcpy(arrayofsign, sign);
while (strlen(arrayofsign) < sizeof(arrayofsign) - 1) {
strcat(arrayofsign, " ");
strncat(arrayofsign, sign,
sizeof(arrayofsign) - 1 - strlen(arrayofsign));
}
if (scanf("%d", &num_of_chars) != 1 || num_of_chars <= 0) {
printf("invalid input\n");
exit(1);
}
for (i = 0;; i = (i + 1) % strlen(sign)) {
printf("[%.*s]\r", num_of_chars, arrayofsign + i);
fflush(stdout);
sleep(1);
}
return 0;
}
I suggest creating a duplicate string that contains the original string, twice. In that case the printing becomes really simple.
Obtain the length of the string, allocate a new string with double the length (don't forget to allocate space for the null terminator), then copy the string into the new string twice. The new string will look like this:
char string[] = "Hello world!" ;
...
char new_string[] = "Hello world!Hello world!" ;
Then simply print it from an offset until you reach the length of the original string and reset the index:
size_t i = 0;
while( 1 )
{
printf( "%.5s" , new_string+i );
i++;
if( i == string_length )
{
i = 0;
}
MoveCursor();
Delay();
}
The number 5 in the printf format syntax "%.5s", means that at most 5 characters of new_string will be printed.
Function MoveCurson should reset the printing position in the console to the start of the line. This function has to be implemented by you, you can start here: Update printf value on same line instead of new one
Function Delay must be implemented by you and it should pause the program for a while. Doing this is platform specific so there is not single answer.
The following program prints all substrings only once:
#include <stdio.h>
#include <string.h>
int main(void)
{
int num_of_chars, i;
char sign[30], two_sign[60];
fgets(sign, sizeof sign, stdin);
scanf("%d", &num_of_chars);
sign[strlen(sign) - 1] = '\0'; // discard '\n'
strcpy(two_sign, sign);
strcat(two_sign, sign);
for (i = 0; sign[num_of_chars + i]; i++)
{
printf("[%.*s]\n", num_of_chars, two_sign + i);
}
return 0;
}
The %.*s enables me to specify the max length of the string to be printed by num_of_chars.
This is what I whipped up real quick.
Commented every line of code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h> /* Use this if windows */
/* #include <unistd.h> for unix and change Sleep to sleep */
char * marquee(char * string, int length, int index)
{
/* string = "Hello, World!!" */
/* Display holds five characters and one for the null */
char * display = malloc(sizeof(char) * (length + 1));
/* This pointer will walk down the string for us */
/* For example: "Hello" then "ello " then "llo H", etc. */
char * travel = malloc(sizeof(char) * 256);
/* This pointer is to concatenate the string that moves off the screen back to the end of travel. This is necessary for the marquee effect. */
/* For example: "Hello World!! " then "ello World!! H" then "llo World!! He" */
char * temp = malloc(sizeof(char) * (strlen(string) + 1));
/* We need a counter to walk through the string */
int counter = 0;
/* Travel should start at the beginning of the string */
/* For example: travel = "Hello, World!!" */
strcpy(travel, string);
/* Loop through string */
while (counter < index)
{
/* First letter of travel needs to equal temp */
/* For example: */
/* First pass: travel[0] = 'H' temp[0] = 'H' */
/* Second pass: travel[0] = 'e' temp[1] = 'e' /*
/* Third pass: travel[0] = 'l' temp[2] = 'l' /*
/* etc... */
temp[counter] = travel[0];
/* Walk down the string */
/* For example: travel = "Hello, World!!", then "ello, World!!", then "llo, World!!" etc. */
travel++;
/* Increment counter to loop through string */
counter = counter + 1;
}
/* We need a null at the end */
temp[counter + 1] = '\0';
/* If we don't add a space at the end, we get a "ello, World!!H" on the next line */
strcat(travel, " ");
/* Second pass: "ello, World!! H" Third pass: "llo, World!! He", etc. */
strcat(travel, temp);
/* Display = "Hello", then "ello ", then "llo H", etc. */
strncpy(display, travel, length);
/* Add the null or else */
display[length] = '\0';
return display;
}
/* This function clears the screen to give the marquee effect.
The following is a system call to the operating system to do the clearing. */
void clrscr()
{
system("#cls||clear");
}
int main()
{
/* Our starting string */
char * string = "Hello, World!!";
/* Get length of string, we'll use it later */
int len = strlen(string);
/* My version of C sucks, so I have to declare this outside the loop*/
int i;
/* Infinite Loop, so marquee never dies */
while (1)
{
/* Loop through entire length of string */
for (i = 0; i < len; i++)
{
/* Get five character string from marquee function */
char * temp = marquee(string, 5, i);
/* Print string...which is only 5 characters big */
printf("%s\n", temp);
/* Sleep for one second or else it will move by too fast to see */
Sleep(1000);
/* Clear Screen */
clrscr();
}
}
return 0;
}
Works, but just realized I didn't bother freeing memory. Hah. Too used to javascript.
You might have to comment out windows.h and comment in unistd.h if you're using UNIX. Also, you would need to make Sleep, sleep (notice the lowercase 's') if you're on UNIX.
// I think i should not help you to do your homework.
#include <stdio.h>
#include <string.h>
void marquee(const char* input, unsigned int loopNumber) {
int start = 0;
size_t inputLen = strlen(input);
while (loopNumber--) {
printf("[");
if (start == inputLen) start = 0;
int end = start + 5;
if (end > inputLen) end -= inputLen;
for (int i = start; i != end; i++) {
if (i == inputLen) i = 0;
printf("%c", input[i]);
}
printf("]\n");
start++;
}
}
int main() {
marquee("Hello world! ", 10);
return 0;
}
I don't know what is the matter.. it works great when I run on my pc but when I submit in uva OJ it says time limit exceeded please help
Here is my solution:
#include <stdio.h>
int main()
{
long int i,j,c,t,k,u,r;
scanf("%d %d",&i,&j);
printf("%d %d",i,j);
r = 0;
if(i>j){
t = i;
i = j;
j = t;
}
for(k = i; k<=j;k++){
c = 1;
u = k;
while(u>1){
if(u%2 == 0)
u = u/2;
else
u = 3*u+1;
c++;
if(c>=r)
r = c;
}
}
printf (" %d",r);
return 0;
}
The following code, on my ubuntu Linux 14.04 takes about 1 second to run, when invoked via:
./untitled > outfile.txt
so perhaps this could be useful.
Note: this will have to be modified significantly for the euler problem
Note: the problem says "UNDER" 1 million, but this code starts at 1 million rather than starting at 999999
// Longest Collatz sequence
// Problem 14
/*
* criteria
* The following iterative sequence is defined for the set of positive integers:
* n → n/2 (n is even)
* n → 3n + 1 (n is odd)
*
* example:
* Using the rule above and starting with 13, we generate the following sequence:
* 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
* It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms.
* Although it has not been proved yet (Collatz Problem),
* it is thought that all starting numbers finish at 1.
*
* the question:
* Which starting number, under one million, produces the longest chain?
*
* Note:
* Once the chain starts the terms are allowed to go above one million.
*/
#include <stdio.h>
// prototypes
void fastWrite( size_t a );
int main( void )
{
#define MAX_START_VALUE (1000000)
size_t LongestChain = 0;
size_t LongestStartValue = 0;
for( size_t i=MAX_START_VALUE; i; i--)
{
size_t chainLength = 0;
size_t result = i;
// for debug
char buffer[] = "current start value:";
for( size_t j=0; buffer[j]; j++) putchar_unlocked( buffer[j] );
putchar_unlocked( ' ');
fastWrite( i );
// end debug
while( result != 1 )
{
chainLength++;
if( result&1 )
{ // then odd
result = 3*result +1;
}
else
{ // else even
result >>= 1;
}
// for debug
//./fastWrite( result );
// end debug
}
chainLength++;
// for debug
char buffer2[] = "chain length: ";
for( size_t k=0; buffer2[k]; k++) putchar_unlocked( buffer2[k] );
fastWrite( chainLength );
putchar_unlocked( '\n' );
// end debug
if ( chainLength > LongestChain )
{
LongestChain = chainLength;
LongestStartValue = i;
}
}
fastWrite( LongestStartValue );
putchar_unlocked('\n');
//putchar_unlocked('\n');
} // end function: main
inline void fastWrite(size_t a)
{
char snum[20];
//printf( "%s, %lu\n", __func__, a );
int i=0;
do
{
// 48 is numeric character 0
snum[i++] = (char)((a%10)+(size_t)48);
a=a/10;
}while(a>0);
i=i-1; // correction for overincrement from prior 'while' loop
while(i>=0)
{
putchar_unlocked(snum[i--]);
}
putchar_unlocked('\n');
} // end function: fastWrite
Just to be helpful with the time taken:
the following are good ways to speed up the I/O
#include <stdio.h>
void fastRead( size_t *a );
void fastWrite( size_t a );
inline void fastRead(size_t *a)
{
int c=0;
// note: 32 is space character
while (c<33) c=getchar_unlocked();
// initialize result value
*a=0;
// punctuation parens, etc are show stoppers
while (c>47 && c<58)
{
*a = (*a)*10 + (size_t)(c-48);
c=getchar_unlocked();
}
//printf( "%s, value: %lu\n", __func__, *a );
} // end function: fastRead
inline void fastWrite(size_t a)
{
char snum[20];
//printf( "%s, %lu\n", __func__, a );
int i=0;
do
{
// 48 is numeric character 0
snum[i++] = (char)((a%10)+(size_t)48);
a=a/10;
}while(a>0);
i=i-1; // correction for overincrement from prior 'while' loop
while(i>=0)
{
putchar_unlocked(snum[i--]);
}
putchar_unlocked('\n');
} // end function: fastWrite
and output characters via:
putchar_unlocked( char );
and always have a final, at end of each test case, the following line:
putchar_unlocked( '\n' );
to input a string of characters, call the following in a loop until a space or newline is encountered
char = getchar_unlocked()
and a final hint: most such problems are easily solved using size_t numeric values, which allows values to 4gig or more. (same as a unsigned long int)
For the current problem. as soon as a chain is calculated, save the chain, perhaps in an array, so you do not have to calculate it again.
Your could pre-calculate the first 'x' chains, say the first 10 for instance, to help with shortening the execution time.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define TAB_STOP 8
/* replaces tabs from input with the proper amount of blank spots */
int Detab()
{
int c, x;
int column;
x = column = 0;
while((c=getchar())!=EOF)
{
if(c == '\n') /* reseting counter if newline */
{
putchar(c);
return 1;
}
else if(c!='\t') /* column counts places to tab spot */
{
putchar(c);
column++;
if(column == TAB_STOP)
column = 0;
}
else /* tab */
{
for(x=0; x<TAB_STOP - column; x++)
putchar('_');
column = 0;
}
}
return 0;
}
#define MAX_ARGUMENTS 100
int main(int argc, char *argv[])
{
int i, val = 0;
int nums[MAX_ARGUMENTS];
int x = 0;
for(i = 1; i < argc; i++) {
while(isdigit(*argv[i])) {
val = val * 10 + *argv[i] - '0';
*++argv[i];
}
if(x > MAX_ARGUMENTS - 1)
return 0;
nums[x++] = val;
nums[x] = '\0';
val = 0;
}
while(Detab(nums));
printf("Press any key to continue.\n");
getchar();
return 0;
}
In main i put all the arguments(numbers) inside nums array and then pass it to detab. So now im interested what would be the smart way to edit detab so it works. I'm still trying to figure out for a working pseudocode but i dont really know.
The way i tought it should work is:
if arguments are 5, 8, 10 then a tab inside first 4 characters leads to position 5, in 5 - 7th char leads to pos 8 etc.
In case of a newline, the arguments start all over again from the begining.
The most common way is to have Detab accept a pointer (which points to an element in an array) and the length of that array:
int Detab(int* data, int len); // access data[0] through data[len - 1]
Call it like so:
void example() {
int array[] = {5, 8, 10};
Detab(array, 3);
// or:
Detab(array, sizeof array / sizeof *array); // second parameter evaluates to 3
// without using a magic constant
}
Here's some pseudocode for expanding tabs:
def expandtabs_in_line(line, tabstops, default, space):
result = ""
for c in line:
if c != "\t":
result += c
else:
for stop in tabstops:
if stop > len(result):
result += space * (stop - len(result))
break
else:
result += space * (default - (len(result) % default))
return result
def expandtabs(lines, tabstops=[], default=8):
for line in lines:
yield expandtabs_in_line(line, tabstops, default, " ")
Try it out at codepad.