473,406 Members | 2,713 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Storing input into a character array

Hi, I'm unhappy: why doesn't this work?

char enc[10000];
char temp[70];

for(int i=0;i<10000;i++){
fscanf(in,"%s",&temp);

if(temp[0]=='#')break;
else
for(int j=0;j<70;j++)
if(temp[j]!='\0')
enc[i]=temp[j];
else break;
}

The input is from a text file (.txt) that contains an encrypted
message between 1 and 10 000 letters long that may be split across
several lines in the input file; each line will contain between 1 and
70 letters inclusive and the final line will contain one #. I want the
entire message to be stored in enc (excluding the #). I thought I'm
using temp to store one line of text, checking if the first character
is a # and if not storing those characters into the next available
slots in the array enc until enc is filled up.

I'm unhappy
Bert
Jun 29 '08 #1
26 3079
Bert said:
Hi, I'm unhappy: why doesn't this work?

char enc[10000];
char temp[70];

for(int i=0;i<10000;i++){
fscanf(in,"%s",&temp);
Several problems here: firstly, you're not protecting your buffer against
inputs longer than 69 characters. Fix that with %69s rather than %s.
Secondly, you're not capturing the return from fscanf to check that the
input succeeded. Fix that with a comparison against 1 (the number of
fields you want to parse). Thirdly, you're using &temp rather than temp -
since temp is (in this context) treated as if it were a pointer to the
first byte in the temp array, the ampersand is not required. Fourthly,
your parse will stop at the first space, which probably isn't what you
want. To fix that, use fgets rather than fscanf. Fifthly, your parse will
fail if the encrypted data you're reading contains a character that your
input routine treats as a sentinel (e.g. newline for fgets), but which is
intended to be part of the data feed. Fix that, if necessary, by reading
fixed-size blocks of input into a buffer (e.g. using fread instead of
fgets) and parse it for the '#' yourself, using e.g. memchr.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 29 '08 #2
Bert wrote:
Hi, I'm unhappy: why doesn't this work?

char enc[10000];
char temp[70];

for(int i=0;i<10000;i++){
fscanf(in,"%s",&temp);

if(temp[0]=='#')break;
else
for(int j=0;j<70;j++)
if(temp[j]!='\0')
enc[i]=temp[j];
else break;
}

The input is from a text file (.txt) that contains an encrypted
message between 1 and 10 000 letters long that may be split across
several lines in the input file; each line will contain between 1 and
70 letters inclusive and the final line will contain one #. I want the
entire message to be stored in enc (excluding the #). I thought I'm
using temp to store one line of text, checking if the first character
is a # and if not storing those characters into the next available
slots in the array enc until enc is filled up.

I'm unhappy
Bert
Jun 29 '08 #3
Bert wrote:
Hi, I'm unhappy: why doesn't this work?

char enc[10000];
char temp[70];

for(int i=0;i<10000;i++){
fscanf(in,"%s",&temp);

if(temp[0]=='#')break;
else
for(int j=0;j<70;j++)
if(temp[j]!='\0')
enc[i]=temp[j];
You're not updating i.
You're writing multiple times to the same location.
else break;
}
Jun 29 '08 #4
On Jun 29, 4:09 pm, Richard Heathfield <r...@see.sig.invalidwrote:
...firstly, you're not protecting your buffer against
inputs longer than 69 characters. Fix that with %69s rather than %s.
I don't need to protect my buffer. This question to be solved just
needs to be solved and not worrying about crashing. Judges want to see
the program work according to the question they've written, not to see
if it is secure code.
Secondly, you're not capturing the return from fscanf to check that the
input succeeded. Fix that with a comparison against 1 (the number of
fields you want to parse).
My comment would be similar to that of above.
Thirdly, you're using &temp rather than temp -
since temp is (in this context) treated as if it were a pointer to the
first byte in the temp array, the ampersand is not required.
Thanks
Fourthly, your parse will stop at the first space, which probably isn't what you
want. To fix that, use fgets rather than fscanf.
Why will my parse stop at the first space and how does fgets work
differently to fscanf?
Fifthly, your parse will fail if the encrypted data you're reading contains a character that your
input routine treats as a sentinel (e.g. newline for fgets), but which is
intended to be part of the data feed. Fix that, if necessary, by reading
fixed-size blocks of input into a buffer (e.g. using fread instead of
fgets) and parse it for the '#' yourself, using e.g. memchr.
The encrypted message will never have spaces nor punctuation in it no
matter how long it ends up being.

Now I'm fairly unhappy
Bert
Jun 29 '08 #5
Bert <al*****************@gmail.comwrites:
On Jun 29, 4:09 pm, Richard Heathfield <r...@see.sig.invalidwrote:
[...]
Fourthly, your parse will stop at the first space, which probably
isn't what you want. To fix that, use fgets rather than fscanf.

Why will my parse stop at the first space and how does fgets work
differently to fscanf?
Because that's what fscanf's "%s" option is defined to do.

Surely you have some reference book that documents all this stuff.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 29 '08 #6
I've changed the code and it now is:

for(int i=0;i<10000;i++){
fgets(in,"%s",temp);

if(temp[0]=='#'){break;
} else {
for(int j=0;j<70;j++)
if(temp[j]!='\0'){
enc[i]=temp[j];
}
else{
break;
}
}
}

Now it doesn't compile.
Can someone please write out what it's supposed to be? I've tried two,
three ways (this is my third attempt) to do this but I can't do it. I
find input so much harder without the string type like in C#.
If you don't write out what it's supposed to be can you write out the
code in pseudocode?
I can store an integer input easily:
fscanf(in,"%d",&rows);
but I can't get this encrypted message working.
I really want to get on to the decryption part of this question yet
I've spent DAYS trying to figure out how to store text input into a
char array and it's a really bad feeling.
My pseudocode was:

Have a counter var. for enc's elements
for(int i=0;i<10000;i++)
Get the next line of the enc. msg - store in temp[]
If the first element of the array (the first character of the
current line's input) is a #, break out of loop.
Else assign the temp[] contents in to enc[]
for(int j=0;j<70;j++)
if(temp[j]!='\0')
enc[i]=temp[j];
else break;
Jun 29 '08 #7
On Sun, 29 Jun 2008 04:54:43 UTC, Bert <al*****************@gmail.com>
wrote:
Hi, I'm unhappy: why doesn't this work?

char enc[10000];
char temp[70];

for(int i=0;i<10000;i++){
fscanf(in,"%s",&temp);

if(temp[0]=='#')break;
else
for(int j=0;j<70;j++)
if(temp[j]!='\0')
enc[i]=temp[j];
else break;
}

The input is from a text file (.txt) that contains an encrypted
message between 1 and 10 000 letters long that may be split across
several lines in the input file; each line will contain between 1 and
70 letters inclusive and the final line will contain one #. I want the
entire message to be stored in enc (excluding the #). I thought I'm
using temp to store one line of text, checking if the first character
is a # and if not storing those characters into the next available
slots in the array enc until enc is filled up.
Beside all that that Richard said already you ignores
- read errors
- EOF, the fact that the file may go out of chars before 10000th char
is readed.
- 10000 chars are commonly unequal to 10000 lines you tries to read.

So you're using a unsuitable function to get your problem resolved.

Your problem is
.. read the file char by char until any char is readed, that is EOF
instead of a char you want shows up
- when the first char of a new line is '#' stop further reading
looks like you means only 'ignore this line' instead of ignore the
whole remaining file

Doing it right you'll be able to encode on the fly instead to use the
wrong and oversized function and copying chars wrongly around.

Hints:
- '\n' tells you that you've readed a whole line completely
- EOF tells you that gthere is no char left in the file
- getc/getchar() returns int, not char
--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2R Deutsch ist da!
Jun 29 '08 #8
Bert wrote:
On Jun 29, 4:09 pm, Richard Heathfield <r...@see.sig.invalidwrote:
[see OP for problem statement]
>...firstly, you're not protecting your buffer against
inputs longer than 69 characters. Fix that with %69s rather than %s.

I don't need to protect my buffer. This question to be solved just
needs to be solved and not worrying about crashing. Judges want to see
the program work according to the question they've written, not to see
if it is secure code.
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
unsigned char *message;
unsigned int msg_length, ctr;
FILE *msg_file;

/* open file containing message */
msg_file = fopen(argv[1], "r");
/* calculate the bytes the file contains */
for (msg_length = 0; fgetc(msg_file) != EOF; msg_length++);
/* adjust for the #EOL on the final line */
msg_length -= 2;
/* allocate an array of sufficient space */
message = malloc(msg_length);
/* read file into array */
rewind(msg_file);
for (ctr = 0; ctr < msg_length; ctr++)
message[ctr] = fgetc(msg_file);
/* print what we have read */
for (ctr = 0; ctr < msg_length; ctr++)
putc(message[ctr], stdout);
fclose(msg_file);
free(message);
return 0;
}

Hope this helps.

Jun 29 '08 #9
Bert said:
On Jun 29, 4:09 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>...firstly, you're not protecting your buffer against
inputs longer than 69 characters. Fix that with %69s rather than %s.
I don't need to protect my buffer.
Yes, you do.
This question to be solved just
needs to be solved and not worrying about crashing. Judges want to see
the program work according to the question they've written, not to see
if it is secure code.
The failure of your customers to request properly-written code does not
give you an excuse to be shoddy.

<snip>
Now I'm fairly unhappy
Learning how to write code properly is not guaranteed to make you happier,
but it can't hurt.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 29 '08 #10
Bert wrote:
Hi, I'm unhappy: why doesn't this work?

char enc[10000];
char temp[70];

for(int i=0;i<10000;i++){
fscanf(in,"%s",&temp);

if(temp[0]=='#')break;
else
for(int j=0;j<70;j++)
if(temp[j]!='\0')
enc[i]=temp[j];
else break;
}

The input is from a text file (.txt) that contains an encrypted
message between 1 and 10 000 letters long that may be split across
several lines in the input file; each line will contain between 1 and
70 letters inclusive and the final line will contain one #. I want the
entire message to be stored in enc (excluding the #). I thought I'm
using temp to store one line of text, checking if the first character
is a # and if not storing those characters into the next available
slots in the array enc until enc is filled up.

I'm unhappy
char enc[10000];
int i, rc;

for(i = 0; 10000 i; ++i) {
rc = getc(in);
if (rc == EOF || rc == '#') {
break;
}
enc[i] = rc;
}

--
pete
Jun 29 '08 #11
pete wrote:
Bert wrote:
>Hi, I'm unhappy: why doesn't this work?

char enc[10000];
char temp[70];

for(int i=0;i<10000;i++){
fscanf(in,"%s",&temp);

if(temp[0]=='#')break;
else
for(int j=0;j<70;j++)
if(temp[j]!='\0')
enc[i]=temp[j];
else break;
}

The input is from a text file (.txt) that contains an encrypted
message between 1 and 10 000 letters long that may be split across
several lines in the input file; each line will contain between 1 and
70 letters inclusive and the final line will contain one #. I want the
entire message to be stored in enc (excluding the #). I thought I'm
using temp to store one line of text, checking if the first character
is a # and if not storing those characters into the next available
slots in the array enc until enc is filled up.

I'm unhappy

char enc[10000];
int i, rc;

for(i = 0; 10000 i; ++i) {
rc = getc(in);
if (rc == EOF || rc == '#') {
break;
}
enc[i] = rc;
}
If you don't want newline characters in your array,
which I think is the case:

char enc[10000];
int rc;
int i = 0;

while (10000 i) {
rc = getc(in);
if (rc == EOF || rc == '#') {
break;
}
if (rc != '\n') {
enc[i++] = rc;
}
}
--
pete
Jun 29 '08 #12
On Jun 29, 5:27*am, pete <pfil...@mindspring.comwrote:
pete wrote:
Bert wrote:
Hi, I'm unhappy: why doesn't this work?
char enc[10000];
char temp[70];
for(int i=0;i<10000;i++){
* * fscanf(in,"%s",&temp);
* * if(temp[0]=='#')break;
* * else
* * * * for(int j=0;j<70;j++)
* * * * * * if(temp[j]!='\0')
* * * * * * * * enc[i]=temp[j];
* * * * * * else break;
}
The input is from a text file (.txt) that contains an encrypted
message between 1 and 10 000 letters long that may be split across
several lines in the input file; each line will contain between 1 and
70 letters inclusive and the final line will contain one #. I want the
entire message to be stored in enc (excluding the #). I thought I'm
using temp to store one line of text, checking if the first character
is a # and if not storing those characters into the next available
slots in the array enc until enc is filled up.
I'm unhappy
char enc[10000];
int i, rc;
for(i = 0; 10000 i; ++i) {
* * rc = getc(in);
* * if (rc == EOF || rc == '#') {
* * * * break;
* * }
* * enc[i] = rc;
}

If you don't want newline characters in your array,
which I think is the case:

char enc[10000];
int rc;
int i = 0;

while (10000 i) {
* * *rc = getc(in);
* * *if (rc == EOF || rc == '#') {
* * * * *break;
* * *}
* * *if (rc != '\n') {
* * * * *enc[i++] = rc;
* * *}

}
But the OP wanted input up to 70 characters. I don't see how your
solution accounts for this.
Chad
Jun 29 '08 #13
Chad wrote:
On Jun 29, 5:27 am, pete <pfil...@mindspring.comwrote:
>pete wrote:
>>Bert wrote:
Hi, I'm unhappy: why doesn't this work?
char enc[10000];
char temp[70];
for(int i=0;i<10000;i++){
fscanf(in,"%s",&temp);
if(temp[0]=='#')break;
else
for(int j=0;j<70;j++)
if(temp[j]!='\0')
enc[i]=temp[j];
else break;
}
The input is from a text file (.txt) that contains an encrypted
message between 1 and 10 000 letters long that may be split across
several lines in the input file; each line will contain between 1 and
70 letters inclusive and the final line will contain one #. I want the
entire message to be stored in enc (excluding the #). I thought I'm
using temp to store one line of text, checking if the first character
is a # and if not storing those characters into the next available
slots in the array enc until enc is filled up.
I'm unhappy
char enc[10000];
int i, rc;
for(i = 0; 10000 i; ++i) {
rc = getc(in);
if (rc == EOF || rc == '#') {
break;
}
enc[i] = rc;
}
If you don't want newline characters in your array,
which I think is the case:

char enc[10000];
int rc;
int i = 0;

while (10000 i) {
rc = getc(in);
if (rc == EOF || rc == '#') {
break;
}
if (rc != '\n') {
enc[i++] = rc;
}

}

But the OP wanted input up to 70 characters. I don't see how your
solution accounts for this.
He wants an entire message from 1 to 10000 letters long,
possibly split into several lines,
to be stored in enc.

The intermediate steps,
which is what the 70 character input is all about,
don't matter.

--
pete
Jun 29 '08 #14
Bert <al*****************@gmail.comwrites:
I've changed the code and it now is:

for(int i=0;i<10000;i++){
fgets(in,"%s",temp);

if(temp[0]=='#'){break;
} else {
for(int j=0;j<70;j++)
if(temp[j]!='\0'){
enc[i]=temp[j];
}
else{
break;
}
}
}

Now it doesn't compile.
[...]

It would be helpful if you'd tell us *how* it doesn't compile
(copy-and-paste the exact message you're getting from your compiler).
Without a complete program, we can't be sure what all the problems
are.

In the meantime, take a look at the line:

fgets(in,"%s",temp);

Why are you passing a format string to fgets? Read the documentation
for the fgets function, and pass it the arguments it's expecting.
--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 29 '08 #15
Why is it that from the input of

3
COPATGAHRRY
#

(in zigin.txt)

that the Y at the end of the encrypted message above isn't outputted
from the following program:

#include <stdio.h>

main()
{
/********************************/
FILE* in=fopen("zigin.txt","r");
char enc[10000];

int numrows, temp;
int numletters = 0;

fscanf(in,"%d",&numrows);

while (10000 numletters)
{
temp = getc(in);

if (temp == EOF || temp == '#')
{
break;
}

if (temp != '\n') {
enc[numletters++] = temp;
}
}
/*********************************/

char row1[numletters/numrows];
char lastrow[numletters/numrows];

char midrows[numrows-2][numletters/numrows+2];
int nlt_inarrays = 0;
/**/
for (int i = 0; i < (numletters/numrows); i++)
{
row1[i] = enc[nlt_inarrays];
++nlt_inarrays;
}
int remaining_letters = numletters % numrows - 3;
int nmidrowswithvalues=0;
for (int i = 0; i < remaining_letters; i++)
{
for (int j = 0; j < (numletters/numrows + 2); j++)
{
midrows[i][j] = enc[nlt_inarrays];
++nlt_inarrays;
}
++nmidrowswithvalues;
}

for (int i = 0; i < (numrows-2-nmidrowswithvalues); i++)
{
for (int j = 0; j < (numletters/numrows + 1); j++)
{
midrows[i+nmidrowswithvalues][j] = enc[nlt_inarrays];
++nlt_inarrays;
}
}
for (int i = 0; i < (numletters/numrows); i++)
{
lastrow[i] = enc[nlt_inarrays];
++nlt_inarrays;
}
/**/
printf("row1 ");
for (int i = 0; i < (numletters/numrows); i++)
{
printf("%c", row1[i]);
}
printf("\n");
for (int i = 0; i < remaining_letters; i++)
{
for (int j = 0; j < (numletters/numrows + 2); j++)
{
printf("%c", midrows[i][j]);
}
printf("\n");
}

for (int i = 0; i < (numrows-2-nmidrowswithvalues); i++)
{
for (int j = 0; j < (numletters/numrows + 1); j++)
{
printf("%c", midrows[i+nmidrowswithvalues][j]);
}
printf("\n");
}

printf("Last row ");
for (int i = 0; i < (numletters/numrows); i++)
{
printf("%c", lastrow[i]);
}
}

I'm annoyed
Bert
Jun 30 '08 #16
Bert <al*****************@gmail.comwrites:
Why is it that from the input of

3
COPATGAHRRY
#

(in zigin.txt)

that the Y at the end of the encrypted message above isn't outputted
from the following program:
It is almost impossible to answers that sort of question. At one
level it is obvious -- the loop that outputs the last row runs three
times from i == 0 while i < 3 (3 is numletters/numrows) -- so it can't
print more than the 3 letters you see "HRR". You can't change the
loop bounds because that (3) is the size of the array you've made.

The trouble I have is that I can't work out what should be happening.
It would help if there were a description of what the program should
do.

--
Ben.
Jun 30 '08 #17
In article <5b**********************************@u36g2000prf. googlegroups.com>,
Bert <al*****************@gmail.comwrote:
>I don't need to protect my buffer. This question to be solved just
needs to be solved and not worrying about crashing. Judges want to see
the program work according to the question they've written, not to see
if it is secure code.
Ahh, you didn't mention that this is a contest and you only want it good
enough to be judged. Or maybe I missed it.

No matter, you should get in the habit of writing correct code from
the get-go, even if the judges don't need it to be really correct.
And besides, I bet style counts for something in this contest, and a
program that checks for errors will score better than one that doesn't.

Anyway, a couple of general issues:

As mentioned elsewhere, if "temp[]" is an array, then "temp" is treated
as a pointer to the start of the array, and you should use it instead of
"&temp" which is meaningless as far as I know.

fscanf() is not nearly as useful as you think it is. As you've already
discovered, %s isn't doing what you thought it would do, but more
importantly, fscanf() is rather squirrely about line endings. It's hard
work to get it right. In general, you want to do fgets() into a buffer,
followed by sscanf() on that buffer. Since you're already using a buffer
anyway, this is no real burden.

Please, please, please get in the habit of checking array bounds and
return codes even if it's just a contest and it doesn't matter. 90%
of the security problems on the internet are caused by programmers who
didn't do these simple things.

Along those lines, you should almost never use sprintf(); use snprintf()
instead. The same is true for any other function that manipulate strings
unless you absolutely, positively trust your source. Likewise, your %s
should have been a %69s as mentioned elsewhere.
--
-Ed Falk, fa**@despams.r.us.com
http://thespamdiaries.blogspot.com/
Jun 30 '08 #18
fa**@green.rahul.net (Edward A. Falk) writes:
[...]
As mentioned elsewhere, if "temp[]" is an array, then "temp" is treated
as a pointer to the start of the array, and you should use it instead of
"&temp" which is meaningless as far as I know.
If temp is an array, then the name temp as an expression is implicitly
converted to a pointer to the array's first element in most, but not
all, contexts. "&temp" is certainly not meaningless; it yields the
address of the array object (which is of a different type than the
address of its first element). See section 6 of the comp.lang.c FAQ
for details.
fscanf() is not nearly as useful as you think it is. As you've already
discovered, %s isn't doing what you thought it would do, but more
importantly, fscanf() is rather squirrely about line endings. It's hard
work to get it right. In general, you want to do fgets() into a buffer,
followed by sscanf() on that buffer. Since you're already using a buffer
anyway, this is no real burden.
Note that sscanf can have problems with numeric data; there's no good
way to handle overflow.

[...]
Along those lines, you should almost never use sprintf(); use snprintf()
instead. The same is true for any other function that manipulate strings
unless you absolutely, positively trust your source. Likewise, your %s
should have been a %69s as mentioned elsewhere.
snprintf() isn't always available; it's new in C99, and most C
implementations don't fully support the C99 standard. sprintf() can
be used safely if you're careful (you have to make sure the target
array is big enough for any possible data).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 30 '08 #19
On Mon, 30 Jun 2008 01:44:00 -0700 (PDT), Bert
<al*****************@gmail.comwrote:
>Why is it that from the input of

3
COPATGAHRRY
#

(in zigin.txt)

that the Y at the end of the encrypted message above isn't outputted
from the following program:
Because after detecting the '#' your program only processes the first
ten letters.

By the way, you ought to fclose the file also.
>
#include <stdio.h>

main()
{
/********************************/
FILE* in=fopen("zigin.txt","r");
char enc[10000];

int numrows, temp;
int numletters = 0;

fscanf(in,"%d",&numrows);

while (10000 numletters)
{
temp = getc(in);

if (temp == EOF || temp == '#')
{
break;
}

if (temp != '\n') {
enc[numletters++] = temp;
}
}
/*********************************/

char row1[numletters/numrows];
char lastrow[numletters/numrows];

char midrows[numrows-2][numletters/numrows+2];
int nlt_inarrays = 0;
/**/
for (int i = 0; i < (numletters/numrows); i++)
{
row1[i] = enc[nlt_inarrays];
You store the first three letters (COP) in row1.
++nlt_inarrays;
}
int remaining_letters = numletters % numrows - 3;
This evaluates to -1.
int nmidrowswithvalues=0;
for (int i = 0; i < remaining_letters; i++)
This loop never executes.
{
for (int j = 0; j < (numletters/numrows + 2); j++)
{
midrows[i][j] = enc[nlt_inarrays];
++nlt_inarrays;
}
++nmidrowswithvalues;
}

for (int i = 0; i < (numrows-2-nmidrowswithvalues); i++)
{
for (int j = 0; j < (numletters/numrows + 1); j++)
{
midrows[i+nmidrowswithvalues][j] = enc[nlt_inarrays];
You store the next 4 letters (ATGA) in midrows[0], even though you
allocated room for 5.
++nlt_inarrays;
}
}
for (int i = 0; i < (numletters/numrows); i++)
{
lastrow[i] = enc[nlt_inarrays];
You store the next 3 letters (HRR) in lastrow.
++nlt_inarrays;
}
/**/
printf("row1 ");
for (int i = 0; i < (numletters/numrows); i++)
{
printf("%c", row1[i]);
}
printf("\n");
for (int i = 0; i < remaining_letters; i++)
{
for (int j = 0; j < (numletters/numrows + 2); j++)
{
printf("%c", midrows[i][j]);
}
printf("\n");
}

for (int i = 0; i < (numrows-2-nmidrowswithvalues); i++)
{
for (int j = 0; j < (numletters/numrows + 1); j++)
{
printf("%c", midrows[i+nmidrowswithvalues][j]);
}
printf("\n");
}

printf("Last row ");
for (int i = 0; i < (numletters/numrows); i++)
{
printf("%c", lastrow[i]);
}
}
You print out 3 + 4 + 3 = 10 letters but your data contained 11.
>I'm annoyed
Bert

Remove del for email
Jul 1 '08 #20
On Jun 30, 5:30*pm, Barry Schwarz <schwa...@dqel.comwrote:
On Mon, 30 Jun 2008 01:44:00 -0700 (PDT), Bert

<albert.xtheunkno...@gmail.comwrote:
Why is it that from the input of
3
COPATGAHRRY
#
(in zigin.txt)
that the Y at the end of the encrypted message above isn't outputted
from the following program:

Because after detecting the '#' your program only processes the first
ten letters.

By the way, you ought to fclose the file also.


#include <stdio.h>
main()
{
* */********************************/
* *FILE* in=fopen("zigin.txt","r");
* *char enc[10000];
* *int numrows, temp;
* *int numletters = 0;
* *fscanf(in,"%d",&numrows);
* *while (10000 numletters)
* *{
* * * *temp = getc(in);
* * * *if (temp == EOF || temp == '#')
* * * *{
* * * * * *break;
* * * *}
* * * *if (temp != '\n') {
* * * * * *enc[numletters++] = temp;
* * * *}
* *}
* */*********************************/
* *char row1[numletters/numrows];
* *char lastrow[numletters/numrows];
* *char midrows[numrows-2][numletters/numrows+2];
* *int nlt_inarrays = 0;
* */**/
* *for (int i = 0; i < (numletters/numrows); i++)
* *{
* * * *row1[i] = enc[nlt_inarrays];

You store the first three letters (COP) in row1.
* * * *++nlt_inarrays;
* *}
* *int remaining_letters = numletters % numrows - 3;

This evaluates to -1.
How do you arrrive at -1 when there doesn't appear to be a value for
'numrows'?
* *int nmidrowswithvalues=0;
* *for (int i = 0; i < remaining_letters; i++)

This loop never executes.
And while I'm having a brainlapse, how do you figure the loop never
executes?

Chad
Jul 1 '08 #21
On Mon, 30 Jun 2008 19:40:09 -0700 (PDT), Chad <cd*****@gmail.com>
wrote:
>On Jun 30, 5:30*pm, Barry Schwarz <schwa...@dqel.comwrote:
>On Mon, 30 Jun 2008 01:44:00 -0700 (PDT), Bert

<albert.xtheunkno...@gmail.comwrote:
>Why is it that from the input of
>3
COPATGAHRRY
#
>(in zigin.txt)
>that the Y at the end of the encrypted message above isn't outputted
from the following program:

Because after detecting the '#' your program only processes the first
ten letters.

By the way, you ought to fclose the file also.


>#include <stdio.h>
>main()
{
* */********************************/
* *FILE* in=fopen("zigin.txt","r");
* *char enc[10000];
* *int numrows, temp;
* *int numletters = 0;
* *fscanf(in,"%d",&numrows);
* *while (10000 numletters)
* *{
* * * *temp = getc(in);
* * * *if (temp == EOF || temp == '#')
* * * *{
* * * * * *break;
* * * *}
* * * *if (temp != '\n') {
* * * * * *enc[numletters++] = temp;
* * * *}
* *}
* */*********************************/
* *char row1[numletters/numrows];
* *char lastrow[numletters/numrows];
* *char midrows[numrows-2][numletters/numrows+2];
* *int nlt_inarrays = 0;
* */**/
* *for (int i = 0; i < (numletters/numrows); i++)
* *{
* * * *row1[i] = enc[nlt_inarrays];

You store the first three letters (COP) in row1.
* * * *++nlt_inarrays;
* *}
* *int remaining_letters = numletters % numrows - 3;

This evaluates to -1.

How do you arrrive at -1 when there doesn't appear to be a value for
'numrows'?
Look at the first executable statement in the function, the one that
calls fscanf.
>
* *int nmidrowswithvalues=0;
* *for (int i = 0; i < remaining_letters; i++)

This loop never executes.

And while I'm having a brainlapse, how do you figure the loop never
executes?
i is 0. remaining_letters is -1. i < remaining_letters evaluates to
false. The loop terminates before the first iteration.

Don't feel bad, it's Monday and we understand.
Remove del for email
Jul 2 '08 #22
Ben Bacarisse wrote:
The more uniform the data structure,
the simpler the program usually is.
What's a data structure and how (have I created)/(am I using) one?
Jul 5 '08 #23
Bert <al*****************@gmail.comwrites:
Ben Bacarisse wrote:
>The more uniform the data structure,
the simpler the program usually is.

What's a data structure and how (have I created)/(am I using) one?
Loosely speaking, a data structure is a collection of data will some
pattern of access. You have made three arrays: one for the top row,
one 2D arrays for the middles rows, and one for the bottom row. Now,
as it happens, you don't need any of that storage but, if you did, I
am saying that you program is likely to be simpler if you just stored
all the rows together in one 2D array. It was an incidental remark.
I think you'll get the best boost from going another way altogether.

--
Ben.
Jul 5 '08 #24
On 29 Jun, 09:53, Bert <albert.xtheunkno...@gmail.comwrote:
I don't need to protect my buffer. This question to be solved just
needs to be solved and not worrying about crashing. Judges want to see
the program work according to the question they've written, not to see
if it is secure code.
Unless the "judges" specifically state "we don't care if your
code is totally insecure and fails to check its input and does
not conform to normal standards of competence" then you need
to consider those things. If the judges do make that statement,
then you need to put as much distance as possible between yourself
and them, since you probably can't learn much from them. If I present
someone with a problem stated like, "suppose you have the following
type of input. Do X with it.", it is assumed that you will know
how to perform the transformation (X); the only thing I'm
really judging is how you deal with the odd cases (bad
input, trivial input, etc.)

It is *never* appropriate to allow a program to crash on
unexpected input.
Jul 5 '08 #25
On Jul 5, 12:44 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
I will post my solution soon
Have you done it yet? I'm just practising past problems for my own
benefit.
Jul 7 '08 #26
Bert <al*****************@gmail.comwrites:
On Jul 5, 12:44 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
>I will post my solution soon

Have you done it yet?
I'd done it when I wrote before. The delay was down to worrying about
posting solutions to homework-type problems.
I'm just practising past problems for my own
benefit.
Then this may be of little use. It is decidedly "compact" because I
wanted to ensure that, if this was homework, my solution would not be
useful as an answer.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void zigzag_decode(int nrows, const char *input)
{
int length = strlen(input);
char output[length + 1];
for (int i = 0, row = 0; i < length; row++) {
output[row] = input[i++];
int skip[] = {nrows - 1 - row, row};
for (int j = 0, p = row; (p += 2 * skip[j]) < length; j = !j)
if (skip[j])
output[p] = input[i++];
}
output[length] = 0;
puts(output);
}

int main(int argc, char **argv)
{
if (argc == 3) {
int nr = atoi(argv[1]);
if (nr 1)
zigzag_decode(nr, argv[2]);
else fprintf(stderr, "Number of rows must be 1.\n");
}
else fprintf(stderr, "Try: zigzag no-of-rows input-sequence\n");
return 0;
}

--
Ben.
Jul 7 '08 #27

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Mark Hannon | last post by:
I am trying to wrap my brain around storing form elements inside variables & arrays before I move on to a more complicated project. I created this simple example to experiment and as far as I can...
10
by: Wonderinguy | last post by:
I have a table with data stored on upper case. I would like to change it proper mixed case. For example : change data from , THIS IS A TEST to This is a test or This Is A Test. Is there any easy...
14
by: deko | last post by:
Is there a way to check user input for illegal characters? For example, a user enters something into a text box and clicks OK. At that point I'd like to run code such as this: illegal =...
3
by: Kay | last post by:
ABC ASF DFS ASS ABC <--- Duplicate JJK I want to store above char in an arry, but I'm not sure I'm right or not anyone can guide me or give me some suggestions, Thx?
8
by: Dawn Minnis | last post by:
Hey guys If I have a program (see codeSnippet1) that I compile to be called test.o Then run it as test.o n n 2 3 4 I want the code to be able to strip out the two characters at the start...
2
by: assgar | last post by:
Hi Developemnt on win2003 server. Final server will be linux Apache,Mysql and PHP is being used. I use 2 scripts(form and process). The form displays multiple dynamic rows with chechboxs,...
20
by: dmurray14 | last post by:
Hey guys, I'm a C++ newbie here - I've messed with VB, but I mostly stick to web languages, so I find C++ to be very confusing at times. Basically, I am trying to import a text file, but I want...
4
by: priyanka | last post by:
Hi, I want to input a string from command line. I use the following program to input the string. #include<stdio.h> int main(){ char input;
24
by: arnuld | last post by:
I have a function named getword that read every single input from std. input. WHAT I WANTED: I want it read the word if it has less than or equal to 30 characters. Anything else beyond that...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.