铸造情况 [英] Contrived casting situation

查看:76
本文介绍了铸造情况的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正在讨论铸造的主题促使我尝试这一点。让''s

说你想用一个包含

17个字符的记录号来填充BankRecord结构(我在下面定义),但将记录号分成SSN

和一个帐号(以及终止''\ 0'')...


#include< stdio.h>

#include< stdlib.h>

#include< string.h>


typedef struct {

char SSN [9];

char AccountNum [8];

char end;

} BankRecord;


int main(int argc,char * argv [])

{

int i;

BankRecord * a ;


if(argc< 2){

printf(" no information provided\\\
);

返回EXIT_FAILURE;

}

if((a = malloc((argc-1)*(sizeof(BankRecord))))== NULL){

printf(" Malloc()failed\\\
);

返回EXIT_FAILURE;

}

for(i = 1; i< argc; i ++){

snprintf((char *)& a [i-1],sizeof(BankRecord),"%s",argv [i]);

}

为(i = 0;我<的argc-1; i ++){

printf("%s \ n",(char *)& a [i]); / *只是为了证明它有效* /

}

返回EXIT_SUCCESS;

}


1)此代码是否合法C? (它编译时没有警告我并正确工作



2)结构演员是否为char *解决这个人为的最佳方法
问题?

3)我怎么能以这样的方式声明BankRecord,以便结束是一个const char

等于''\''' ?这是否可取?

4)还有其他评论吗?


-

Christopher Benson-Manica | Jumonji giri,荣誉。

ataru(at)cyberspace.org |

解决方案

Christopher Benson-Manica写道:< blockquote class =post_quotes>
正在讨论演员的主题促使我尝试这一点。让我们说你想用一个带有
17个字符的记录号来填充BankRecord结构(我在下面定义),但记录号分为SSN
和一个帐号(以及终止''\ 0'')......

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

typedef struct {
char SSN [9];
char AccountNum [8];
char end;
} BankRecord ;

int main(int argc,char * argv [])
{
int i;
BankRecord * a;

如果(argc< 2){
printf(没有提供信息\ n);
返回EXIT_FAILURE;
}
if((a = malloc((argc-) 1)*(sizeof(BankRecord))))== NULL){
printf(" Malloc()failed\\\
);
返回EXIT_FAILURE;
}
for(i = 1; i< argc; i ++){
snprintf((char *)& a [i-1],sizeof(BankRecord),"%s",argv [i]); <无线电通信/>}
for(i = 0;我<的argc-1; i ++){
printf("%s \ n",(char *)& a [i]); / *只是为了证明它有效* /
}
返回EXIT_SUCCESS;
}

1)这段代码是否合法C? (它编译时没有警告我并正确工作



代码是合法的从某种意义上说,它没有表现出任何未定义的行为(除非我错过了什么)。但是,

它并不严格符合,因为它有实现 -

定义的行为:sizeof(BankRecord)至少为18,但

可能由于结构中的填充而变得更大。因此,当给出一个20个字符的命令行时,程序的输出结果可能是b
$ b参数取决于实现的细节。


简而言之:不保证第九个输入

字符落在AccountNum [0]点;它可能会在SSN和AccountNum之间陷入困境。代码

有效,但可能没有做你想要的。

2)结构的演员是char *是解决这个人为的最佳方法问题?


不,因为它调用了上面提到的实现定义的行为

因此不可移植。

3)怎么能我以这样的方式声明BankRecord,以便结束是一个const char
等于''\ 0''?这会是可取的吗?


通过声明无法实现这一目标。是否

这是一个理想的事态是一个品味问题 - 如果你需要C ++和构造函数,你知道在哪里可以找到它们。

4)还有其他任何意见吗?




是的:写下你的意思,不是别的你想要的东西

of think might产生同样的效果。如果你有两个

不同的值 - SSN和AccountNum - 就这样对待它们。

如果你想将它们视为单个的子字段更大的

字符串,声明一个18元素的数组包含

单个更大的字符串。


猜猜:你有没有在FORTRAN上切牙,也许

变得过于喜欢EQUIVALENCE宣言?如果是这样,

我的建议是在写C时失去这个习惯。


-
Er ********* @ sun.com


Christopher Benson-Manica写道:

正在讨论铸造的线程促使我尝试这一点。让我们说你想用一个带有
17个字符的记录号来填充BankRecord结构(我在下面定义),但记录号分为SSN
和一个帐号(以及终止''\ 0'')......

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

typedef struct {
char SSN [9];
char AccountNum [8];
char end;
} BankRecord ;

int main(int argc,char * argv [])
{
int i;
BankRecord * a;

如果(argc< 2){
printf(没有提供信息\ n);
返回EXIT_FAILURE;
}
if((a = malloc((argc-) 1)*(sizeof(BankRecord))))== NULL){
printf(" Malloc()failed\\\
);
返回EXIT_FAILURE;
}
for(i = 1; i< argc; i ++){
snprintf((char *)& a [i-1],sizeof(BankRecord),"%s",argv [i]); <无线电通信/>}
for(i = 0;我<的argc-1; i ++){
printf("%s \ n",(char *)& a [i]); / *只是为了证明它有效* /
}
返回EXIT_SUCCESS;
}

1)这段代码是否合法C? (它编译时没有警告我正确地工作
正确)


是的。

2)结构的演员是否为char *解决这个人为问题的最佳方法是什么?


您可以使用工会,但我认为这不会更好。

3)我如何以这样的方式申报BankRecord那个结尾是一个const char
等于''\ 0''?这会是可取的吗?


你不能。在某种程度上这是可取的,但我认为它会在语言中产生很多复杂性,很快就会破坏它的b $ b b的可取性。

4)还有其他评论吗?




我认为如果传递的参数太长,snprintf中的a [i-1]

调用最终会无效。我想也许sscanf会更好因为

你可以在格式说明符中指定长度,即使使用了整个长度,它也会附加一个

null。除此之外,我认为这是一个有效的代码。


Matt Gregory





Christopher Benson-Manica写道:

正在讨论演员的主题促使我尝试这一点。让我们说你想用一个带有
17个字符的记录号来填充BankRecord结构(我在下面定义),但记录号分为SSN
和一个帐号(以及终止''\ 0'')......

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

typedef struct {
char SSN [9];
char AccountNum [8];
char end;
} BankRecord ;

int main(int argc,char * argv [])
{
int i;
BankRecord * a;

如果(argc< 2){
printf(没有提供信息\ n);
返回EXIT_FAILURE;
}
if((a = malloc((argc-) 1)*(sizeof(BankRecord))))== NULL){
printf(" Malloc()failed\\\
);
返回EXIT_FAILURE;
}
for(i = 1; i< argc; i ++){
snprintf((char *)& a [i-1],sizeof(BankRecord),"%s",argv [i]); <无线电通信/>}
for(i = 0;我<的argc-1; i ++){
printf("%s \ n",(char *)& a [i]); / *只是为了证明它有效* /


你应该尝试另一个测试:

printf(" AccountNum =%s \ n,a [i] .Accountum);

并查看它是否仍按预期工作。

}
返回EXIT_SUCCESS;
}

1)这段代码是否合法C? (它编译时没有警告我并且正确地工作了
2)结构的演员是char *解决这个人为的问题的最佳方法吗?




不,你有结构成员填充的问题,地址在

fag问题2.13和2.12

http://www.eskimo.com/~scs/C-faq /q2.13.html
http://www.eskimo.com/~scs/C-faq/q2.12.html


-

Al Bowers

坦帕,美国佛罗里达州

mailto: xa*@abowers.combase.com (删除x)
http://www.geocities。 com / abowers822 /


The thread where casting is being discussed motivated me to try this. Let''s
say you wanted to populate a BankRecord structure (as I defined below) with
17-character record numbers, but with the record numbers separated into a SSN
and an account number (and with a terminating ''\0'')...

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

typedef struct {
char SSN[9];
char AccountNum[8];
char end;
} BankRecord;

int main( int argc, char * argv[] )
{
int i;
BankRecord *a;

if( argc < 2 ) {
printf( "No information provided\n" );
return EXIT_FAILURE;
}
if( (a=malloc((argc-1)*(sizeof(BankRecord)))) == NULL ) {
printf( "Malloc() failed\n" );
return EXIT_FAILURE;
}
for( i=1; i < argc; i++ ) {
snprintf( (char*)&a[i-1], sizeof(BankRecord), "%s", argv[i] );
}
for( i=0; i < argc-1; i++ ) {
printf( "%s\n", (char*)&a[i] ); /* just to prove that it works */
}
return EXIT_SUCCESS;
}

1) Is this code legal C? (it compiled with no warnings for me and worked
correctly)
2) Is the cast of a structure to a char* the best way to solve this contrived
problem?
3) How can I declare BankRecord in such a way so that end is a const char
equal to ''\0''? Would that be desirable?
4) Any other comments?

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |

解决方案

Christopher Benson-Manica wrote:


The thread where casting is being discussed motivated me to try this. Let''s
say you wanted to populate a BankRecord structure (as I defined below) with
17-character record numbers, but with the record numbers separated into a SSN
and an account number (and with a terminating ''\0'')...

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

typedef struct {
char SSN[9];
char AccountNum[8];
char end;
} BankRecord;

int main( int argc, char * argv[] )
{
int i;
BankRecord *a;

if( argc < 2 ) {
printf( "No information provided\n" );
return EXIT_FAILURE;
}
if( (a=malloc((argc-1)*(sizeof(BankRecord)))) == NULL ) {
printf( "Malloc() failed\n" );
return EXIT_FAILURE;
}
for( i=1; i < argc; i++ ) {
snprintf( (char*)&a[i-1], sizeof(BankRecord), "%s", argv[i] );
}
for( i=0; i < argc-1; i++ ) {
printf( "%s\n", (char*)&a[i] ); /* just to prove that it works */
}
return EXIT_SUCCESS;
}

1) Is this code legal C? (it compiled with no warnings for me and worked
correctly)
The code is "legal" in the sense that it exhibits no
undefined behavior (unless I''ve missed something). However,
it is not strictly conforming because it has implementation-
defined behavior: sizeof(BankRecord) is at least 18, but
might be larger because of padding within the struct. Thus,
the program''s output when given a 20-character command-line
argument, say, depends on the details of the implementation.

In short: It is not guaranteed that the ninth input
character lands in the AccountNum[0] spot; it might instead
land in the limbo between SSN and AccountNum. The code
works, but might not be doing what you want.
2) Is the cast of a structure to a char* the best way to solve this contrived
problem?
No, because it invokes the implementation-defined behavior
mentioned above and is thus not portable.
3) How can I declare BankRecord in such a way so that end is a const char
equal to ''\0''? Would that be desirable?
There''s no way to achieve this with a declaration. Whether
that''s a desirable state of affairs is a matter of taste -- if
you want C++ and constructors, you know where to find them.
4) Any other comments?



Yes: Write what you mean, not something else that you sort
of think might produce the same effect. If you''ve got two
distinct values -- SSN and AccountNum -- treat them as such.
If you want to view them as sub-fields of a single larger
string, declare a single 18-element array to contain that
single larger string.

A guess: Did you cut your teeth on FORTRAN, and perhaps
become overly fond of the EQUIVALENCE declaration? If so,
my recommendation is to lose that habit when writing C.

--
Er*********@sun.com


Christopher Benson-Manica wrote:

The thread where casting is being discussed motivated me to try this. Let''s
say you wanted to populate a BankRecord structure (as I defined below) with
17-character record numbers, but with the record numbers separated into a SSN
and an account number (and with a terminating ''\0'')...

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

typedef struct {
char SSN[9];
char AccountNum[8];
char end;
} BankRecord;

int main( int argc, char * argv[] )
{
int i;
BankRecord *a;

if( argc < 2 ) {
printf( "No information provided\n" );
return EXIT_FAILURE;
}
if( (a=malloc((argc-1)*(sizeof(BankRecord)))) == NULL ) {
printf( "Malloc() failed\n" );
return EXIT_FAILURE;
}
for( i=1; i < argc; i++ ) {
snprintf( (char*)&a[i-1], sizeof(BankRecord), "%s", argv[i] );
}
for( i=0; i < argc-1; i++ ) {
printf( "%s\n", (char*)&a[i] ); /* just to prove that it works */
}
return EXIT_SUCCESS;
}

1) Is this code legal C? (it compiled with no warnings for me and worked
correctly)
Yep.
2) Is the cast of a structure to a char* the best way to solve this contrived
problem?
You could use a union, but I don''t think that would be better.
3) How can I declare BankRecord in such a way so that end is a const char
equal to ''\0''? Would that be desirable?
You can''t. It would be desirable in a way, but I think it would create
a lot of complexities in the language that would quickly defeat its
desirability.
4) Any other comments?



I think if the argument passed is too long, the a[i-1] in the snprintf
call will end up null-less. I think maybe sscanf would be better because
you can specify the length in the format specifier and it will append a
null even if the entire length is used. Other than that I think its a
valid piece of code.

Matt Gregory




Christopher Benson-Manica wrote:

The thread where casting is being discussed motivated me to try this. Let''s
say you wanted to populate a BankRecord structure (as I defined below) with
17-character record numbers, but with the record numbers separated into a SSN
and an account number (and with a terminating ''\0'')...

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

typedef struct {
char SSN[9];
char AccountNum[8];
char end;
} BankRecord;

int main( int argc, char * argv[] )
{
int i;
BankRecord *a;

if( argc < 2 ) {
printf( "No information provided\n" );
return EXIT_FAILURE;
}
if( (a=malloc((argc-1)*(sizeof(BankRecord)))) == NULL ) {
printf( "Malloc() failed\n" );
return EXIT_FAILURE;
}
for( i=1; i < argc; i++ ) {
snprintf( (char*)&a[i-1], sizeof(BankRecord), "%s", argv[i] );
}
for( i=0; i < argc-1; i++ ) {
printf( "%s\n", (char*)&a[i] ); /* just to prove that it works */
You should try another test:
printf("AccountNum = %s\n",a[i].Accountum);
and see if it still works as expected.
}
return EXIT_SUCCESS;
}

1) Is this code legal C? (it compiled with no warnings for me and worked
correctly)
2) Is the cast of a structure to a char* the best way to solve this contrived
problem?



No, You have issues of struct member padding which are address in
fag questions 2.13 and 2.12

http://www.eskimo.com/~scs/C-faq/q2.13.html
http://www.eskimo.com/~scs/C-faq/q2.12.html

--
Al Bowers
Tampa, Fl USA
mailto: xa*@abowers.combase.com (remove the x)
http://www.geocities.com/abowers822/


这篇关于铸造情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆