代码不适用于通用类型向量< T>在C ++中 [英] Code not working for generic type vector<T> in C++

查看:118
本文介绍了代码不适用于通用类型向量< T>在C ++中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将图像发送到服务器。之前我有一个简单的函数

I am trying to send images to server. Earlier I had a simple function

void fileSend(const char* fpath)

这个函数能够将一个图像文件发送到服务器。但是,我应该立刻向服务器发送许多图像,这就是为什么我去了矢量< t>。我用

This function is able to send one image file to the server. But, I am supposed to send many images to the server at once, that is why I went for vector<t>. I overloaded the previous method with

void fileSend(const vector<string>& fnames)

重载了前一个方法但是现在程序突然停止而没有发送任何图像。我试着找到问题,但我无法理解发生了什么。函数失败

But now the program stops abruptly without sending any images. I tried finding the problem, but I am not able to understand what is happening. It fails in function

void fileSend(const vector<string>& fnames)

当我调用重载方法

fileSend(fnames[k].c_str());

请帮助



我的尝试:



Please help

What I have tried:

void fileSend(const char *fpath)
	{
		// Extract only filename from given path.
		char filename[50];
		int i = strlen(fpath);
		for (; i > 0; i--)
		{
			if (fpath[i - 1] == '\\')
				break;
		}
		for (int j = 0; i <= (int)strlen(fpath); i++)
		{
			filename[j++] = fpath[i];
		}

		ifstream myFile(fpath, ios::in | ios::binary | ios::ate);
		int size = (int)myFile.tellg();
		myFile.close();

		char filesize[10]; itoa(size, filesize, 10);
		send(sock, filename, strlen(filename), 0);
		char rec[32] = ""; recv(sock, rec, 32, 0);

		send(sock, filesize, strlen(filesize), 0);
		recv(sock, rec, 32, 0);

		FILE *fr = fopen(fpath, "rb");

		while (size > 0)
		{
			char buffer[1030];

			if (size >= 1024)
			{
				fread(buffer, 1024, 1, fr);
				send(sock, buffer, 1024, 0);
				recv(sock, rec, 32, 0);
			}
			else
			{
				fread(buffer, size, 1, fr);
				buffer[size] = '\0';
				send(sock, buffer, size, 0);
				recv(sock, rec, 32, 0);
			}
			size -= 1024;
		}
		fclose(fr);
	}

	void fileSend(const vector<string>& fnames)
	{
		for (int k = 0; k < fnames.size(); k++)
		{
			fileSend(fnames[k].c_str()); // call the original function
		}
	}



我在main()中调用此函数为:


I am calling this function in main() as:

vector<string> filenames;
	string path = "C:\\Images:\\";
	string imageName;
	string fullPath;
	int numberOfImages;

	while (true)
	{
		cout << "Enter the number of images you want to send : ";
		cin >> numberOfImages;

		for (int i = 0; i < numberOfImages; i++)
		{
			cout << "Select an image:";
			cin >> imageName;
			fullPath = path + imageName;
			filenames.push_back(fullPath);
		}

		client.fileSend(filenames);
}



客户端是类Client的对象,我编写了函数fileSend()


client is an object of class Client where I have written the functions fileSend()

推荐答案

路径声音:
string path = "C:\\Images:\\";

第二个:



解决此问题并调试代码。可能是因为您希望重载的调用未得到解决。尝试重命名一个函数。

with the second ":"

Resolve this and debug the code.Maybe the overloaded call isnt resolved as you wish. Try to rename one function.


您的代码中没有明确的概念,您正在为类似的任务混合使用C和C ++库函数(例如,使用C ++和C流进行文件操作)。 br />


我实际上并没有看到你的代码失败的地点和原因,但这里有一些提示:



您的代码不会检查错误。您应该检查可能返回错误状态并处理异常的每个函数的返回值(例如,当打开 ifstream 的文件失败时)。一旦错误中断执行并显示错误消息。



获取指向给定完整路径的文件名的指针非常简单(你的代码太复杂了,那里不需要带有const字符串的额外缓冲区):

There is no clear concept in your code and you are mixing C and C++ library functions for similar tasks (e.g. using C++ and C streams for file operations).

I don't see actually where and why your code fails, but here are some tips:

Your code does not check for errors. You should check the return value of each function that might return an error state and handle exceptions (e.g. when opening the a file with ifstream fails). Upon errors break execution and display an error message.

Getting a pointer to the file name for a given full path is quite simple (your code is much too complicated and there is no need for an additional buffer with const strings):
const char * filename = strrchr(fpath, '\\');
if (filename)
    filename++;
else
    filename = fpath;



然后你发送两个字符串但没有尾随NULL。接收器应该如何知道他必须读取多少字节?

此问题的常见解决方案是首先发送大小(作为二进制值而不是字符串),然后是内容。这种实现称为传输协议,应在编写任何代码行之前定义。它通常通过定义结构来实现。在您的情况下,它可能看起来像:


Then you are sending two strings but without the trailing NULL. How does the receiver should know how many bytes he has to read?
The common solution for this problem is sending the sizes first (as binary values and not as strings) followed by the content. Such an implementation is called a transfer protocol and should be defined before writing any code line. It is usally implemented by defining a structure. In your case it might look like:

#include <stdint.h>

struct myprotocol {
    uint32_t namelen;
    uint32_t filesize;
    char filename[1];
};

它可以像

It can be used like

uint8_t buf[sizeof(myprotocol) + MAX_FILE_NAME_LEN];
prot * myprotocol = static_cast<myprotocol*>(buf);
prot->namelen = strlen(filename);
prot->filesize = filesize;
strcpy(prot->filename, filename);
if (send(socket, buf, sizeof(myprotocol) + prot->namelen, 0) < 0)
{
    // Report error here
    return; // May also return error indicator or code (errno) here
}
// Now send image data

接收器可以使用类似的缓冲区并读取 sizeof(myprotocol)进入该缓冲区。然后他可以在相应的缓冲区位置读取 namelen 字节,然后读取图像数据:

The receiver can use a similar buffer and read sizeof(myprotocol) into that buffer. Then he can read namelen bytes at the corresponding buffer location followed by reading the image data:

// Error checking omitted in this example!

// Receive the header
recv(socket, buf, sizeof(myprotocol), 0);
// Receive the remaining name characters (first already read above)
recv(socket, &prot->filename[1], prot->namelen, 0);
// Receive now prot->filesize image data bytes



这种方法的优点是接收器确切地知道已经发送了多少字节,并且可以相应地提供或分配缓冲区。



如果你的程序仍然没有按预期工作(显示没有现在提供的错误消息),你应该在调试器中运行它。


The advantage of this method is that the receiver exactly knows how many bytes has been send and can provide or allocate buffers accordingly.

If your program still not works as expected then (showing no now provided error messages), you should run it within a debugger.


这篇关于代码不适用于通用类型向量&lt; T&gt;在C ++中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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