LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

newline character

Hi everybody.
While I was writing an smtp client, I discovered a possibly obscure
feature. To terminate the mail, the SMTP protocol requires a
"\n\r.\n\r" string. It did not work in any way, so I tried to print on
a file. This is the code:

#include
#include
int main (int argc, char *argv[])
{
FILE *f;
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
f = fopen ("test1.txt", "w");
fprintf (f, "\n\r.\n\r");
fclose (f);
return 0;
}

then I opened the file with an hex editor, and I found:
0D 0A 0D 2E 0D 0A 0D
This is not what I expected. Then I tried:
fprintf (f, "\n");
in the same code, and discovered that \n is not translated as a single
character as it should be (according to Kernighan and Ritchie's "The C
pr
ogramming language", a fundamental text), but it is translated as
\0x0D\0x0A. I think that this is platform dependent, and might depend
on how Windows separes lines as opposed to UNIX.
Anyway, the result of strlen("\n") is 1, not 2. This is a bit
confusing.
Even worst, I tried:
fprintf (f, "\x0A");
and the result is still 0D 0A.
So, how can one print on a file the character 0A without the fprintf
adding other things? And what does the ANSI standard say on this?
Hope someone can help me.
Thanks.
0 Kudos
Message 1 of 5
(3,973 Views)
Hi,

You will get the result required if you open the file in binary mode,
f= fopen ("test1.txt", "wb");
not
f= fopen ("test1.txt", "w");

I can't comment on K&R or ANSI but "wb" always writes data exactly as
specified on all platforms I've used it on. There are cross platform
differences for line ends (which implies a text file) between UNIX &
DOS/Windows and I suspect you are seeing that in operation (UNIX uses
'\n' only).

Regards,

John Cameron.

RE newline character,
Elio Fungi said;
>Hi everybody.
>While I was writing an smtp client, I discovered a possibly obscure
>feature. To terminate the mail, the SMTP protocol requires a
>"\n\r.\n\r" string. It did not work in any way, so I tried to print on
>a file. This is the code:
>
>#include
>#
include
>int main (int argc, char *argv[])
>{
> FILE *f;
> if (InitCVIRTE (0, argv, 0) == 0)
> return -1; /* out of memory */
> f = fopen ("test1.txt", "w");
> fprintf (f, "\n\r.\n\r");
> fclose (f);
> return 0;
>}
>
>then I opened the file with an hex editor, and I found:
>0D 0A 0D 2E 0D 0A 0D
>This is not what I expected. Then I tried:
> fprintf (f, "\n");
>in the same code, and discovered that \n is not translated as a single
>character as it should be (according to Kernighan and Ritchie's "The C
>programming language", a fundamental text), but it is translated as
>\0x0D\0x0A. I think that this is platform dependent, and might depend
>on how Windows separes lines as opposed to UNIX.
>Anyway, the result of strlen("\n") is 1, not 2. This is a bit
>confusing.
>Even worst, I tried:
> fprintf (f, "\x0A");
>and the result is still 0D 0A.
>So, how can one print on a file the character 0A without the fprintf
>adding
other things? And what does the ANSI standard say on this?
>Hope someone can help me.
>Thanks.
0 Kudos
Message 2 of 5
(3,973 Views)
John Cameron wrote in message news:...
> Hi,
>
> You will get the result required if you open the file in binary mode,
> f= fopen ("test1.txt", "wb");
> not
> f= fopen ("test1.txt", "w");
>
Ok, thanks a lot, it was useful.
But, in the case of smtp client, I have the following code:

char msg[MSGLEN];
sprintf (msg, "\n.\n");
ClientTCPWrite ((unsigned int)smtpHandle, msg, strlen(msg), SMTP_TIMEOUT);

Again, the server expects CRLF.CRLF sequence: the code above works, whilst
sprintf (msg, "\n\r.\n\r");
does not. So, when I use ClientTCPWrite, how can I send binary data?
Thanks for your patience.
0 Kudos
Message 3 of 5
(3,973 Views)
I assume this behaviour depends on the conversion implemented by the OS in interpreting the 'new line' character \n (which in Windows is automatically converted to 0D 0A).

You could try setting manually the escape codes required without the printf facility, that is:

int len;
char msg[MSGLEN];
strcpy (msg, "Hello world");
len = strlen (msg);
msg[len++) = 0x0A;
msg[len++) = 0x0D;
msg[len++) = 0x2E;
msg[len++) = 0x0A;
msg[len++) = 0x0D;
msg[len++) = 0x0;

This way your string should be exactly what you write to it, without any additional character added by the OS or the compiler.

My 2 cents.
Roberto


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 4 of 5
(3,973 Views)
Hi,

I hesitate to reply as I don't really have an answer but as no one else
has offered anything better I suggest you write your own test server.

You can run this on the same PC (just leave your client programme server
IP address blank) and examine the data transferred to the server
programme. At least this will tell you if the CVI TCP library is doing
what you expect.

You might consider modifying a copy of the sample TCP server.

Regards,

JC.

RE newline character,
Elio Fungi said;
>John Cameron wrote in message
>news:...
>> Hi,
>>
>> You will get the result required if you open the file in binary mode,
>> f= fopen ("test1.txt", "wb");
>> not
>> f= fopen ("test1.txt",
"w");
>>
>Ok, thanks a lot, it was useful.
>But, in the case of smtp client, I have the following code:
>
>char msg[MSGLEN];
>sprintf (msg, "\n.\n");
>ClientTCPWrite ((unsigned int)smtpHandle, msg, strlen(msg), SMTP_TIMEOUT);
>
>Again, the server expects CRLF.CRLF sequence: the code above works, whilst
>sprintf (msg, "\n\r.\n\r");
>does not. So, when I use ClientTCPWrite, how can I send binary data?
>Thanks for your patience.

Hi,

I hesitate to reply as I don't really have an answer but as no one else
has offered anything better I suggest you write your own test server.

You can run this on the same PC (just leave your client programme server
IP address blank) and examine the data transferred to the server
programme. At least this will tell you if the CVI TCP library is doing
what you expect. If it is then you can at least look beyond CVI.

You might consider modifying a copy of the sample TCP server.

If you've done this already, sorry for the obvious advice:-)

--
Regards,

Joh
n Cameron.
0 Kudos
Message 5 of 5
(3,973 Views)